Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Simpler by Design: Build a Better GraphQL API for Your Next App by Writing Less Code (MOB301) - AWS re:Invent 2018

138 views

Published on

Building a scalable API for your mobile app can be daunting. Between authentication, authorization, database, real-time and offline considerations and the soft requirements of serverless scalability, expandability, security, and availability, the API can become complicated. In this session, learn how to easily build a serverless GraphQL API for your next app without needing to be an API expert, then integrate it into your app with just a few lines of code. Accelerate your app development by simplifying your backend design.

  • Be the first to comment

Simpler by Design: Build a Better GraphQL API for Your Next App by Writing Less Code (MOB301) - AWS re:Invent 2018

  1. 1. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Simpler By Design: Build A Better GraphQL API For Your Next App By Writing Less Code Michael Paris SDE AWS M O B 3 0 1
  2. 2. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. What do modern web & mobile apps need? What is AWS AppSync? What is AWS Amplify? How does it fit together and help you build applications? Agenda
  3. 3. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. A few things every app needs Development User management & Authorization Real-time APIs Client SDKs and tooling Deployment Multiple environments Hosting CI / CD Analytics
  4. 4. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. How do we get there? User management & Authorization Amazon Cognito User Pools Real-time APIs AWS AppSync Client SDKs and tooling Amplify Framework Multiple environments Amplify CLI Hosting & CI / CD AWS Amplify Console Analytics Amazon Pinpoint
  5. 5. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. A managed GraphQL gateway. Define the shape of your API using GraphQL schema definition language (SDL) Attach data sources that reference other AWS resources Write resolvers that fetch data from data sources and attach them to fields A real-time data broker. Subscribe to any mutation out of the box Reliable message delivery via MQTT over WebSockets What is AWS AppSync?
  6. 6. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. A Basic AWS AppSync API AWS Customer Account Post Table type Mutation { createPost(...): Post updatePost(...): Post deletePost(...): Post } type Query { getPost(...): Post listPosts(...): Post } type Subscription { onCreatePost(...): Post onUpdatePost(...): Post onDeletePost(...): Post } type Post { id: ID! title: String createdAt: String updatedAt: String } Schema Resolvers DataSources AWS AppSync createPost updatePost deletePost getPost listPosts Mutation Query Post Table DataSource Post Table ARN IAM Role ARN
  7. 7. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. “GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.” graphql.org What is GraphQL?
  8. 8. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. A query language for APIs… Queries read data Mutations write data Subscriptions are pushed data in real-time query GetPost { getPost(id: ”1”) { id title } } mutation CreatePost { createPost(title: “GraphQL @re:invent”) { id title } } subscription OnCreatePost { onCreatePost { id title } }
  9. 9. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. A runtime for fulfilling those queries with your existing data
  10. 10. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. A complete and understandable description of the data in your API… schema { query: Query mutation: Mutation } type Query { # Get a post by id. getPost(id: ID!): Post # Paginate through posts listPosts(limit: Int, nextToken: String): PostConnection }
  11. 11. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Gives clients the power to ask for exactly what they need and nothing more query GetPostAndComments { getPost(id: “1”) { id title comments { id content } } } { “data”: { “getPost”: “id”: “1”, ”title”: “GraphQL @re:invent”, “comments”: [ { “id”: “2”, “content”: “Love it!” } ] } } }
  12. 12. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Makes it easier to evolve APIs over time … type Post { # The editor of the post. editor: User @deprecated(reason: “Replacing with multiple editors”) # A set of editors for the post. editors: [User] }
  13. 13. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. And enables powerful developer tools…
  14. 14. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. A framework that provides an integrated developer experience for web & mobile apps using AWS Categories include api, auth, storage, analytics, and more First class support for React, Angular, Ionic, React Native, iOS, Android Opinionated solutions to problems that every app developer faces A CLI that coordinates the moving parts Deploy full application backends in a few key strokes Supports multiple environments for multi user team collaboration What is AWS Amplify?
  15. 15. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. AWS Amplify $ amplify init $ amplify add auth $ amplify add storage $ amplify add api $ amplify push Initialize an Amplify project Add an Amazon Cognito User Pool Create and secure an Amazon Simple Storage Service (Amazon S3) bucket Add an AWS AppSync API Deploy via AWS CloudFormation
  16. 16. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Rapidly build scalable, data-driven applications Declaratively define your app’s data model using GraphQL SDL and have it transformed into a fully descriptive AWS CloudFormation stack Powered by GraphQL directives @model, @auth, @connection, @versioned, and @searchable The GraphQL Transform
  17. 17. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Let’s look at a few examples
  18. 18. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. The @model transformer # schema.graphql type Post @model { id: ID! title: String! } $ amplify add api
  19. 19. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. $ amplify push
  20. 20. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. And voila! AWS Customer Account Post Table type Mutation { createPost(...): Post updatePost(...): Post deletePost(...): Post } type Query { getPost(...): Post listPosts(...): Post } type Subscription { onCreatePost(...): Post onUpdatePost(...): Post onDeletePost(...): Post } type Post { id: ID! title: String createdAt: String updatedAt: String } Schema Resolvers DataSources AWS AppSync createPost updatePost deletePost getPost listPosts Mutation Query Post Table DataSource Post Table ARN IAM Role ARN
  21. 21. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Your API is ready to go. Let’s query it.
  22. 22. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Create an object mutation CreatePost { createPost(input: { title: “A new post!” }) { id title } } PutItem { “data”: { “createPost”: { ”id”: “1”, “title”: “A new post!” } } }
  23. 23. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Get an object query GetPost { getPost( id: ”1” ) { id title } } GetItem { “data”: { “getPost”: { ”id”: “1”, “title”: “A new post!” } } }
  24. 24. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. List and paginate objects query ListPosts { listPosts(limit: 10, nextToken: “...”) { items { id title } nextToken } } Scan/Query { “data”: { “listPosts”: { “items”: [{ ”id”: “1”, “title”: “A new post!” }], “nextToken”: “...” } } }
  25. 25. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. { “data”: { “updatePost”: { ”id”: “1”, “title”: “A different post!” } } } Update an object mutation UpdatePost { updatePost(input: { id: “1”, title: “A different post!” }) { id title } } DynamoDB UpdateItem
  26. 26. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Delete an object mutation DeletePost { deletePost(input: { id: “1” }) { id title } } DynamoDB DeleteItem { “data”: { “deletePost”: { ”id”: “1”, “title”: “A different post!” } } }
  27. 27. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. @auth (static group) type Post @model @auth(rules: [ { allow: groups, groups: ["Admin"] } ]) { id: ID! title: String! } Admin AWS Cloud Amazon DynamoDB Post Table type Mutation { createPost(...): Post updatePost(...): Post deletePost(...): Post } type Query { getPost(...): Post listPosts(...): Post } type Subscription { onCreatePost(...): Post onUpdatePost(...): Post onDeletePost(...): Post } Schema Resolvers DataSources AWS AppSync createPost updatePost deletePost getPost listPosts Mutation Query Post Table DataSource Post Table ARN IAM Role
  28. 28. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. @auth (dynamic group) type Post @model @auth(rules: [{ allow: groups, groupsField: “allowedGroups” }]) { id: ID! title: String! allowedGroups: [String!]! } allowedGroups field, mutations will fail and queries will return null. AWS Cloud Amazon DynamoDB Post Table type Mutation { createPost(...): Post updatePost(...): Post deletePost(...): Post } type Query { getPost(...): Post listPosts(...): Post } type Subscription { onCreatePost(...): Post onUpdatePost(...): Post onDeletePost(...): Post } Schema Resolvers DataSources AWS AppSync createPost updatePost deletePost getPost listPosts Mutation Query Post Table DataSource Post Table ARN IAM Role
  29. 29. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. @auth (ownership) type Post @model @auth(rules: [ { allow: owner, ownerField: “editors” } ]) { id: ID! title: String! editors: [String!]! } editors field, mutations will fail and queries will return null. AWS Cloud Amazon DynamoDB Post Table type Mutation { createPost(...): Post updatePost(...): Post deletePost(...): Post } type Query { getPost(...): Post listPosts(...): Post } type Subscription { onCreatePost(...): Post onUpdatePost(...): Post onDeletePost(...): Post } Schema Resolvers DataSources AWS AppSync createPost updatePost deletePost getPost listPosts Mutation Query Post Table DataSource Post Table ARN IAM Role
  30. 30. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. @auth (combo) type Post @model @auth(rules: [ { allow: groups, groups: [“Admin”] }, { allow: owner, ownerField: “editors” } ]) { id: ID! title: String! editors: [String!]! } AWS Cloud Amazon DynamoDB Post Table type Mutation { createPost(...): Post updatePost(...): Post deletePost(...): Post } type Query { getPost(...): Post listPosts(...): Post } type Subscription { onCreatePost(...): Post onUpdatePost(...): Post onDeletePost(...): Post } Schema Resolvers DataSources AWS AppSync createPost updatePost deletePost getPost listPosts Mutation Query Post Table DataSource Post Table ARN IAM Role
  31. 31. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. @connection type Post @model { id: ID! title: String! comments: [Comment!]! @connection(name: “PostComments”) } type Comment @model { id: ID! content: String! post: Post @connection(name: “PostComments”) } AWS Cloud Amazon DynamoDB Post Table type Mutation { createPost(...): Post updatePost(...): Post deletePost(...): Post createComment(...): Comment updateComment(...): Comment deleteComment(...): Comment } type Query { getPost(...): Post listPosts(...): Post getComment(...): Comment listComment(...): Comment } type Subscription { onCreatePost(...): Post onUpdatePost(...): Post onDeletePost(...): Post onCreateComment(...): Comment onUpdateComment(...): Comment onDeleteComment(...): Comment } Schema Resolvers DataSources AWS AppSync Mutation Query Post DataSource Post Table ARN IAM Role Comment Table Comment DataSource Post Table ARN IAM Role createComment updateComment deleteComment deletePost updatePost createPost getPost listPosts getComment listComments Post comments Comment post gsi-PostComments
  32. 32. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Querying with @connection query GetPostAndComments { getPost(id: ”1”) { id title comments(limit: 10, nextToken: “...”) { items { id content } nextToken } } } gsi-PostComments
  33. 33. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. @versioned type Post @model @versioned { id: ID! title: String! } type Post { id: ID! title: String! version: Int! } input UpdatePostInput { id: ID! title: String expectedVersion: Int! } # Also added to DeletePostInput
  34. 34. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Querying with @versioned mutation CreatePost { createPost(input: { title: “A new post!” }) { id title version } } “data” “createPost” { “id”: “1”, “title”: “A new post!”, “version”: 1 }
  35. 35. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Querying with @versioned mutation UpdatePost { updatePost(input: { id: “1”, title: “An updated post!”, expectedVersion: 1 }) { id title version } } “data” “updatePost” { “id”: “1”, “title”: “An updated post!”, “version”: 2 }
  36. 36. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Querying with @versioned
  37. 37. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Querying with @versioned mutation UpdatePost { updatePost(input: { id: “1”, title: “I prefer this title!”, expectedVersion: 1 }) { id title version } } ConditionalUpdateFailedException conflict detection
  38. 38. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. @searchable type Post @model @searchable { id: ID! title: String! } AWS Cloud Amazon DynamoDB Post Table type Mutation { createPost(...): Post updatePost(...): Post deletePost(...): Post } type Query { getPost(...): Post listPosts(...): Post } type Subscription { onCreatePost(...): Post onUpdatePost(...): Post onDeletePost(...): Post } Schema Resolvers DataSources AWS AppSync createPost updatePost deletePost getPost listPosts Mutation Query Post Table DataSource Post Table ARN IAM Role AWS Lambda Streaming Lambda Amazon Elasticsearch Service Amazon ElasticSsarch Service searchPosts ElasticSearch DataSource ES Domain ARN IAM Role
  39. 39. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Search objects query SearchPosts { searchPosts(filter: { title: { match: “new” } }) { items { id title } } } { “data”: { “searchPosts”: { “items”: [{ ”id”: “1”, “title”: “A new post!” }] } } }
  40. 40. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Simple, declarative configuration. Design your data model & let the tool do the work. Works seamlessly with the Amplify Framework. Instant offline & real-time support in client apps. All data is stored in your AWS Account. Use all the other great tools & services AWS has to offer. Amplify API Overview
  41. 41. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. The Amplify Library
  42. 42. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. The Amplify Library Easily connect AWS services to web and mobile apps. Categories include API, Analytics, Auth, Function, Storage, etc Simple to use abstractions for common use cases. Support for many frameworks & platforms. React, React-Native, iOS, Android, Ionic, Angular, etc.
  43. 43. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Configure Amplify import Amplify from 'aws-amplify’; import awsconfig from './aws-exports’; Amplify.configure(awsconfig);
  44. 44. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Add the <Authenticator /> component import React, { Component } from 'react'; import { Authenticator } from 'aws-amplify-react'; class Home extends Component { render() { return ( <div className="container home"> ... <Authenticator onStateChange={this.handleAuthStateChange} amplifyConfig={awsExports} errorMessage={authErrorMessageMapper} /> ... </div> ); } }
  45. 45. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Provide data with <Connect /> <Connect query={gql(queries.GetConvo, { id: this.props.conversation.id })} subscription={gql(subscriptions.OnCreateMessage, { conversationId: this.props.conversation.id})} onSubscriptionMsg={(prev, { onCreateMessage }) => { addToEnd(prev.getConvo.messages.items, onCreateMessage) return prev; }} > {({ data, loading, error }) => { // Uses render props to provide data to child components if (error) return (<h3>Error: {error}</h3>); if (loading) return (<h3>Loading...</h3>); const messages = getIn(data, “getConvo.messages.items”); return ( <div> { messages.map((message, i) => ( <ChatMessage key={i} message={message} isFromMe={message.authorId === me.username} /> )) } </div> )}} </Connect>
  46. 46. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Call mutations with API import * as mutations from './graphql/mutations'; import { graphqlOperation, Analytics, API } from 'aws-amplify’; async function createMessage(message) { const response = await API.graphql( graphqlOperation(mutations.CreateMessage, { input: message }) ); return response.data.createMessage; }
  47. 47. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Instrument analytics import React, { Component } from 'react'; import { Analytics } from 'aws-amplify’; class App extends Component { componentDidMount() { Analytics.startSession(); window.addEventListener('beforeunload', () => { Analytics.stopSession(); }) } ... }
  48. 48. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Amplify Codegen $ amplify add codegen $ amplify codegen # Generate queries & native types from your GraphQL API # for iOS, Android, TypeScript, and Flow
  49. 49. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Multi environment support $ git branch prod $ git push origin prod # Map git branches to Amplify environments # Amplify console make CI / CD & hosting a breeze
  50. 50. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Demo
  51. 51. Thank you! © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved. Michael Paris parismic@amazon.com @mikeparisstuff
  52. 52. © 2018, Amazon Web Services, Inc. or its affiliates. All rights reserved.

×