GraphQL : Evolution of Modern Age Database Management System

The word GraphQL keeps popping up a lot around the web. It has been mentioned in many technical events as well, the most recent being the AWS re:Invent 2017, where they announced AppSync, a fully managed GraphQL service.

The word GraphQL keeps popping up a lot around the web. It has been mentioned in many technical events as well, the most recent being the AWS re:Invent 2017, where they announced AppSync, a fully managed GraphQL service.

Why is GraphQL suddenly making ripples in the developer community and how does it’s rise impact the tech world?

While the name can mislead you to believe it to be a query language it is a replacement for REST (and its alternate versions). I have compiled the key takeaways for anyone who is wanting to understand GraphQL.

To help you better understand and highlight the differences I have included illustrated examples using REST and HTTP.


What is GraphQL?

GraphQL was developed by Facebook internally in 2012 and was later released to the public in October 2015. In facebook terminology: GraphQL is a query language designed to build client applications by providing an intuitive, flexible syntax and system for describing their data requirements and interactions. It provides a language to query data from backends and change data on them.

In a nutshell, GraphQL is a query language created by Facebook, that specifies how to ask data from APIs.


The basics of GraphQL

GraphQLhas 3 high-level operations:

  • Queries – Used to fetch data, like GET method in REST
  • Mutations – Used to create/modify data followed by fetch, like POST, PUT, DELETE methods in REST
  • Subscriptions – Long Lived connections to receive updates on data from the server, like web sockets

These operations are exposed via a schema that defines the capabilities of an API. A schema is composed of types. The schema defined by the developer determines the capability of the GraphQL API.

Every GraphQL API can have two types:

  • Root types, e.g. query, mutation, subscription
  • User-defined types, e.g. todo, human, animal, etc.

Every GraphQL API will have a query type and may or may not have a mutation and subscription type. The root types determine the entry point of the GraphQL query.

Example query:

{
human(id: 101) {
name
age
}
}

The above query does the following:

  1. Starts with the root object
  2. We select the human with id 101 field on that
  3. For a hero object returned, we select the name and age fields

The result of the query will be:

{
“data”: {
“human”: {
“name”: “John Doe”,
“age”: 20
}
}
}

For the above query to work we must add a human type to the schema which consists of the fields that it can return. The type of root query and human is as follows:

type Human {
name: String!
age: Int!
}
type Query {
human(id: ID!): Human
}

The fields of a type need to return some data. This happens in a GraphQL. API is through a concept known as a GraphQL resolver. This is a function that either calls out to a data source or invokes a trigger to return some value (such as an individual record or a list of records).

Resolvers can have many types of data sources, such as NoSQL databases, relational databases, or REST APIs. We can aggregate data from multiple data sources and return identical types, mixing and matching to meet your needs.

After a schema is connected to a resolver function, a client app can issue a GraphQL query or, optionally, a mutation or subscription. I am sure you have started to see how GraphQL, is different from its predecessors and other commonly used databases.

However, does it have actual benefits? Let’s take a look.


Benefits of GraphQL
  • Better data retrieval

Querying data is very simple and round trips to the servers are reduced. Consider a blog that has content, comments etc. Every comment can have description and users, every user will have name, email, list of blogs.

Imagine I need the blog contents with the comment, the user who commented and that user’s blogs. To achieve it we will have to make the following REST calls

  1.  GET – api/vi/blogs/101/ -> will return the blog with its contents
  2.  GET – api/v1/blogs/101/comments -> will return the comments of the blog
  3.  GET – api/v1/users/30/blogs -> will return the blogs of the user

Say we had 4 comments hence N = 4 so the number of calls needed to be made are Step 1 + Step 2 + Step 3 x 4 which evaluates to 6 calls. We require the blogs of all the users who commented on the blog so step 3 will have to be performed multiple N times depending upon the number of users.

Now the exact same thing can be archived in 1 call when using GraphQL using the below query

{
blog(id: 101) {
content
comments {
content
users {
name
email
blog {
content
}
}
}
}
}

Did you notice how we can replace several lines of code with just one simple logic?


  • Better versioning

In a REST API if there is a new field or some change in the resource a new version of the endpoint must be created. This incurs managing more code, another endpoint and removing the old endpoint once deprecated.

GraphQL solves this problem by allowing the user to keep the same endpoint while adding new fields to the type dynamically without breaking any existing stuff


  • Better control of the response data

Consider we have an API that is consumed by a responsive web application. Depending upon the device where the app has opened the data displayed on the screen will vary, some fields may be hidden on smaller screen devices and all the fields may be shown on devices with a larger screen.

The following infographic explains various pain points, pertaining to manage data returned when using REST:

With GraphQL it’s just a matter of querying the fields that are required depending upon the device. The front end is in control of the data it requests, and the same principles can be utilized for any GraphQL API


  • Aggregate data

With GraphQL we can easily aggregate data from different sources and serve it up to the users under a single umbrella rather than making multiple REST calls from the front end or back end. We can expose a legacy system through a unified API.

As mentioned above every GraphQL API is composed of types, schema and resolvers. In order create an API we require to create a GraphQL server in some language. As you know by now GraphQL is a language in its own and has a specification, the specification must be implemented in a programming language to be utilized.

Almost all modern programming languages now have an implementation of the GraphQL specification that you can utilize. Hence making integration and migration extremely smooth and easy.


Important Resources:

As a programmer, I am sure you are eager to try out GraphQL. I have compiled some useful tools and libraries that you can utilize to make your journey with GraphQL more fun.

graphql – A implementation of the GraphQL in JS

Apollo – A toolkit for GraphQL. It has implementations of server for multiple platforms

Prisma – A tool to turn your database into a GraphQL API. It supports multiple databases

Scaphold – A hosted GraphQL backend

AWS AppSync – A hosted GraphQL server that is fully managed AWS and connects to multiple data sources


Conclusion:

GraphQL is very powerful and has a lot of potentials, but it is still in its infancy. However, in a short period of time, it has gained a lot of traction and has been widely adopted by the community.

The popularity clearly goes on to show the ease of use and the importance of GraphQL. The benefits that I have discussed here are just some of the ones that I have experienced while using it first-hand.

As the system evolves I am sure a lot more would be unsurfaced – there is a huge ecosystem where GraphQL can be utilized.


At Cuelogic Technologies we make use of cutting edge and modern age technology to deliver products and intelligence that is future proof, self-learning and with 0 technical debt. We are one of the top outsource software development companies. GraphQL is one of the very many futuristic technologies we are working with.

www.cuelogic.com

 

If you are social give us a shout out!

Learn GraphQL - Zero To GraphQL

Learn GraphQL - Zero To GraphQL

Learn GraphQL - Zero To GraphQL. Learn how to adapt your existing ORM, SOA, or REST API to GraphQL so that you can begin to use GraphQL-based technologies like Relay today.

Learn how to adapt your existing ORM, SOA, or REST API to GraphQL so that you can begin to use GraphQL-based technologies like Relay today.

GraphQL Recipes - Building APIs with GraphQL Transform

GraphQL Recipes - Building APIs with GraphQL Transform

The GraphQL Transform library allows you to deploy AWS AppSync GraphQL APIs with features like NoSQL databases, authentication, ...

To view the repo only containing the code and instructions for deploying these applications, click here.

In this post I've created annotated GraphQL schemas that you can use to deploy popular types of applications.

The GraphQL Transform library allows you to deploy AWS AppSync GraphQL APIs with features like NoSQL databases, authentication, elasticsearch engines, lambda function resolvers, relationships, authorization, and more using GraphQL schema directives.

For example, take the following schema that is utilizing the @modeldirective:

type Note @model {
  id: ID!
  name: String!
  description: String
}

This schema will deploy the following:

  1. GraphQL API
  2. CRUD GraphQL operations for this base type: Create, Read, Update, Delete, and List
  3. GraphQL subscriptions (triggered by mutation events; create, update, delete)
  4. DynamoDB NoSQL Database
  5. GraphQL resolvers mapping the DynamoDB table to the GraphQL CRUD operations

As of this post there are 7 directives offered by the GraphQL Transform library:

@model
// Deploys DynamodDB + resolvers + additional GraphQL schema

@auth
// Allows the definition of auth rules and builds corresponding GraphQL resolvers based on these rules

@connection
// Enables you to specify relationships between `@model` object types 

@searchable
// Handles streaming the data of an @model object type to Amazon Elasticsearch Service and configures search resolvers that search that information

@function
//  Allows you to quickly & easily configure AWS Lambda resolvers within your AWS AppSync API

@key
// Enables you to configure custom index structures for @model types

@versioned
// Adds object versioning and conflict resolution to a type

Using this library you can deploy the back end for your application using only an annotated GraphQL schema.

In this post I will show example schemas that, when used with the Amplify GraphQL transform library, will build out the backends for many popular types of applications.

  1. Todo App
  2. Events App
  3. E Commerce App
  4. WhatsApp Clone
  5. Reddit Clone
  6. Chat App
  7. Instagram Clone
  8. Conference App

For a tutorial showing how to deploy these applications using the GraphQL transform library, check out the documentation here.> Some applications may require additional custom authorization logic for certain subscriptions that you may not want accessible to all users. To learn more, check out the documentation here.## Testing these out

To deploy any of these applications, run the following commands:

Be sure to first install the AWS Amplify CLI

$ amplify init

# if the app needs auth
$ amplify add auth

$ amplify add api

> Choose GraphQL
> If using authentication, choose Amazon Cognito as authentication type
> Update GraphQL schema

# if the app needs storage (i.e. images or video)
$ amplify add storage

$ amplify push

Testing locally

You can now use local mocking to test serverless GraphQL APIs, databases, and serverless functions locally.

$ amplify mock api

Check out this video for a quick overview of local testing:

Todo App

Let's start with something very basic: a Todo app.

This app has the following requirements. The user should be able to:

  1. List all Todos
  2. Create, update, and delete Todos

Based on these requirements we can assume we need the following for this application:

  1. Todo type
  2. Database
  3. GraphQL definition for mutations (create, update, delete todos)
  4. GraphQL definition for queries (listTodos)
  5. GraphQL resolvers for all operations

To build this app, we could use the following annotated GraphQL schema:

type Todo @model {
  id: ID!
  name: String!
  description: String
}

This will deploy the entire GraphQL API including the DynamoDB NoSQL database, additional GraphQL schema for GraphQL CRUD and List operations, GraphQL subscriptions, and the GraphQL resolvers mapping the schema to the database.

Events App

Next, let's look at how we might create an events app. A point to notice here is that we will need to have a way for admins to be able to create, update, and delete events and guests to only be able to read events. We also want to be able to query and get a sorted list (by date) of the events.

Based on these requirements, the user should be able to:

  1. List events in order by date of event
  2. View individual event

An admin should also be able to:

  1. Create an event
  2. Update and delete an event

To build this app, we could use the following annotated GraphQL schema:

type Event
  @model
  @key(name: "queryName", fields: ["queryName", "time"], queryField: "eventsByDate")
  @auth(rules: [{allow: groups, groups: ["Admin"], operations: [create, update, delete]}])
  {
    id: ID!
    name: String!
    description: String
    time: String!
    queryName: String!
}

When creating a new event, we would need to populate the queryNameparameter with a consistent value in order to be able to sort by time of the event:

mutation createEvent {
  createEvent(input: {
    name: "Rap battle of the ages"
    description: "You don't want to miss this!"
    time: "2018-07-13T16:00:00Z"
    queryName: "Event"
  }) {
    id name description time
  } 
}

Note: because queryName will be the same ("Event") value across all items, you could also update the resolver request mapping template to auto-populate this value and therefore not need to specify it in the mutation.
Now, to query for a list of sorted events, you could use the following query:

query listEvents {
  eventsByDate(queryName: "Event") {
    items {
      id
      name
      description
      time
    }
  }
}

Once you've created the authentication by running amplify add auth, you can run amplify console auth to add a user to the Admin group or use a Lambda Trigger to do it automatically when certain users sign up.

E-commerce App

This app has the following requirements. The User should be able to:

  1. Create an account
  2. View products
  3. Purchase products
  4. View order / orders

An admin should be able to:

  1. Create, update, and delete products, orders, and users

Based on these requirements we can assume we need the following for this application:

  1. Product, Customer, and Order types
  2. Database
  3. GraphQL definition for mutations (create, update, delete products, customers, and orders)
  4. GraphQL definition for queries (get, list)
  5. GraphQL resolvers for all operations

To build this app, we could use the following annotated GraphQL schema:

type Customer
  @model(subscriptions: null)
  @auth(rules: [
    { allow: owner }, { allow: groups, groups: ["Admin"]}
  ]) {
  id: ID!
  name: String!
  email: String!
  address: String
}

type Product @model
  @auth(rules: [
    {allow: groups, groups: ["Admin"], operations: [create, update, delete]}
  ]) {
  id: ID!
  name: String!
  description: String
  price: Float!
  image: S3Object
}

type S3Object {
  bucket: String!
  region: String!
  key: String!
}

type Order @model
  @auth(rules: [
   {allow: owner}, {allow: groups, groups: ["Admin"]}
  ]) {
  id: ID!
  customer: Customer @connection
  total: Float!
  order: String
}

WhatsApp Clone

This app has the following requirements. The User should be able to:

  1. Create an account
  2. Update their profile with their avatar image
  3. Create a conversation
  4. Create a message in a conversation

Based on these requirements we can assume we need the following for this application:

  1. User, Conversation, and Message types
  2. Database
  3. GraphQL definition for mutations (create, update, delete users, conversations, and messages)
  4. GraphQL definition for queries, mutations, and subscriptions
  5. GraphQL subscriptions for real-time communication
  6. GraphQL resolvers for all operations

To build this app, we could use the following annotated GraphQL schema:

type User 
  @model 
  @auth(rules: [
    { allow: owner, ownerField: "id", operations: [create, update, delete] }
    ]) {
  id: ID!
  username: String!
  avatar: S3Object
  conversations: [ConvoLink] @connection(name: "UserLinks")
  messages: [Message] @connection(name: "UserMessages")
    createdAt: String
    updatedAt: String
}

type Conversation
  @model(subscriptions: null)
  @auth(rules: [{ allow: owner, ownerField: "members" }]) {
  id: ID!
  messages: [Message] @connection(name: "ConvoMsgs", sortField: "createdAt")
  associated: [ConvoLink] @connection(name: "AssociatedLinks")
  name: String!
  members: [String!]!
    createdAt: String
    updatedAt: String
}

type Message 
  @model(subscriptions: null, queries: null) 
  @auth(rules: [{ allow: owner, ownerField: "authorId" }]) {
  id: ID!
  author: User @connection(name: "UserMessages", keyField: "authorId")
  authorId: String
  content: String!
  image: S3Object
  conversation: Conversation! @connection(name: "ConvoMsgs", sortField: "createdAt")
  messageConversationId: ID!
    createdAt: String
    updatedAt: String
}

type ConvoLink 
  @model(
    mutations: { create: "createConvoLink", update: "updateConvoLink" }
    queries: null
    subscriptions: null
  ) {
  id: ID!
  user: User! @connection(name: "UserLinks")
  convoLinkUserId: ID
  conversation: Conversation! @connection(name: "AssociatedLinks")
  convoLinkConversationId: ID!
    createdAt: String
    updatedAt: String
}

type Subscription {
  onCreateConvoLink(convoLinkUserId: ID!): ConvoLink
    @aws_subscribe(mutations: ["createConvoLink"])
  onCreateMessage(messageConversationId: ID!): Message
    @aws_subscribe(mutations: ["createMessage"])
}

type S3Object {
  bucket: String!
  region: String!
  key: String!
}

Reddit Clone

This app has the following requirements. The User should be able to:

  1. Create an account
  2. Create & delete a post (post can be an image or text)
  3. Comment on a post
  4. Vote on a post
  5. Vote on a comment

Based on these requirements we can assume we need the following for this application:

  1. User, Post, Comment, and Vote types
  2. Database
  3. GraphQL definition for mutations (create, update, delete users, posts and comments)
  4. GraphQL definition for queries
  5. GraphQL resolvers for all operations

To build this app, we could use the following annotated GraphQL schema:

type User 
  @model 
  @auth(rules: [
    { allow: owner, ownerField: "id", operations: [create, update, delete] }
    ]) {
  id: ID!
  username: String!
  posts: [Post] @connection
    createdAt: String
    updatedAt: String
}

type Post @model @auth(rules: [{allow: owner, operations: [create, update, delete]}]) {
  id: ID!
  postContent: String
  postImage: S3Object
  comments: [Comment] @connection
  votes: Int
}

type Comment @model @auth(rules: [{allow: owner, operations: [create, update, delete]}]) {
  id: ID!
  text: String!
  author: String!
  votes: Int
  post: Post @connection
}

type Vote @model
  @key(name: "byUser", fields: ["createdBy", "createdAt"], queryField: "votesByUser")
  {
  id: ID!
  postId: ID!
  createdBy: ID!
  createdAt: String!
  vote: VoteType
}

type S3Object {
  bucket: String!
  region: String!
  key: String!
}

input VoteInput {
    type: VoteType!
    id: ID!
}

enum VoteType {
    up
    down
}

Voting

For the voting mechanism to work, we need to make sure that the resolver is incrementing or decrementing the votes count directly at the DB level. To do that, you will need to create a new mutation and request mapping template to increment and decrement the vote on an item (comment or post).

First, add the following types to your GraphQL schema:

voteForPost(input: ItemVoteInput): Post

input ItemVoteInput {
  type: ItemVoteType!
  id: ID!
}

enum ItemVoteType {
  up
  down
}

Then create a custom resolver that would look something like this.

#set($vote = 1)
#if ($context.arguments.input.type == "down")
  #set($vote = -1)
#end

{
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key" : {
        "id" : { "S" : "${context.arguments.input.id}" }
    },
    "update" : {
        "expression" : "ADD votes :votes",
        "expressionValues" : {
            ":votes" : { "N" : $vote }
        }
    }
}

Now, when creating a vote, you will need to do two things:

  1. Make sure that each vote made by the user has a unique id. To do that, you can use a combination of the user ID + the id of the item being voted on.
  2. Make sure the user has already not voted the same vote. To do so, you could query by id of the vote (userId + item ID), then if the item is there check to see if the vote is different. If it is, update it. If it's the same, then do nothing. If it doesn't exist, create the vote.

You also have the ability to query all votes from a user.

Chat App

Click here to view AWS AppSync Chat, a completed full-stack version of this app built with React.
This app has the following requirements. The User should be able to:

  1. Create an account
  2. Create a conversation
  3. Create a message in a conversation
  4. View a list of all conversations
  5. Have the ability to create a new conversation with another user

Based on these requirements we can assume we need the following for this application:

  1. User, Conversation, and Messsage types
  2. Database
  3. GraphQL definition for mutations (create, update, delete users, conversations and messages)
  4. GraphQL definition for queries
  5. GraphQL resolvers for all operations

To build this app, we could use the following annotated GraphQL schema:

type User 
  @model 
  @auth(rules: [
    { allow: owner, ownerField: "id", operations: [create, update, delete] }
    ]) {
  id: ID!
  username: String!
  conversations: [ConvoLink] @connection(name: "UserLinks")
  messages: [Message] @connection(name: "UserMessages")
    createdAt: String
    updatedAt: String
}

type Conversation
  @model(subscriptions: null)
  @auth(rules: [{ allow: owner, ownerField: "members" }]) {
  id: ID!
  messages: [Message] @connection(name: "ConvoMsgs", sortField: "createdAt")
  associated: [ConvoLink] @connection(name: "AssociatedLinks")
  name: String!
  members: [String!]!
    createdAt: String
    updatedAt: String
}

type Message 
  @model(subscriptions: null, queries: null) 
  @auth(rules: [{ allow: owner, ownerField: "authorId" }]) {
  id: ID!
  author: User @connection(name: "UserMessages", keyField: "authorId")
  authorId: String
  content: String!
  conversation: Conversation! @connection(name: "ConvoMsgs", sortField: "createdAt")
  messageConversationId: ID!
    createdAt: String
    updatedAt: String
}

type ConvoLink 
  @model(
    mutations: { create: "createConvoLink", update: "updateConvoLink" }
    queries: null
    subscriptions: null
  ) {
  id: ID!
  user: User! @connection(name: "UserLinks")
  convoLinkUserId: ID
  conversation: Conversation! @connection(name: "AssociatedLinks")
  convoLinkConversationId: ID!
    createdAt: String
    updatedAt: String
}

type Subscription {
  onCreateConvoLink(convoLinkUserId: ID!): ConvoLink
    @aws_subscribe(mutations: ["createConvoLink"])
  onCreateMessage(messageConversationId: ID!): Message
    @aws_subscribe(mutations: ["createMessage"])
}

Instagram Clone

This app has the following requirements. The User should be able to:

  1. Create an account
  2. Create a post
  3. Create a comment on a post
  4. Follow and unfollow a user
  5. Like a comment or a post

Based on these requirements we can assume we need the following for this application:

  1. User, Post, Like, Following, and Comment types
  2. Database
  3. GraphQL definition for mutations (create, update, delete users, posts, comments, following, and likes)
  4. GraphQL definition for queries
  5. GraphQL resolvers for all operations

To build this app, we could use the following annotated GraphQL schema:

type User 
  @model 
  @auth(rules: [
    { allow: owner, ownerField: "id", operations: [create, update, delete] }
    ]) {
  id: ID!
  username: String!
  posts: [Post] @connection
  createdAt: String
  updatedAt: String
}

type Post @model @auth(rules: [
  {allow: owner, operations: [create, update, delete]}
]) {
  id: ID!
  postImage: S3Object!
  comments: [Comment] @connection
  likes: Int
}

type Comment @model @auth(rules: [{allow: owner, operations: [create, update, delete]}]) {
  id: ID!
  text: String!
  author: String!
  likes: Int
  post: Post @connection
}

type Like @model
  @key(name: "byUser", fields: ["createdBy", "createdAt"], queryField: "likesByUser")
  {
  id: ID!
  postId: ID!
  createdBy: ID!
  createdAt: String!
  liked: Boolean
}

type Following @model @key(name: "followerId", fields: ["followerId", "createdAt"], queryField: "listFollowing") {
  id: ID
  followerId: ID!
  followingId: ID!
  createdAt: String!
}

type S3Object {
  bucket: String!
  region: String!
  key: String!
}

Likes

Similarly to the Reddit clone, we need to have some custom logic in our resolver to handle likes. In the case of Instagram, you probably only want a user to like a post a single time. If they tap like again, you may want to allow them to unlike a post.

We'll also probably want to keep a total count of likes for a post and for a comment. Luckily, this isn't that hard to accomplish. With DynamoDB (or any NoSQL database) we can do this directly in a database operation without having to first read from the database.

To implement the like count, we can first create the following GraphQL mutation definition:

likePost(like: Boolean!): Post
#set($like = true)
#if ($context.arguments.like == false")
  #set($like = -1)
#end

{
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key" : {
        "id" : { "S" : "${context.arguments.input.id}" }
    },
    "update" : {
        "expression" : "ADD likes :likes",
        "expressionValues" : {
            ":likes" : { "N" : $like }
        }
    }
}

Conference App

Click here to view Conference App in a Box, a completed full-stack version of this app built with React Native.
This app has the following requirements. The User should be able to:

  1. Create an account
  2. View a list of talks
  3. View an individual talk
  4. Create a comment on a talk
  5. (optional) Report a comment

An Admin should be able to:

  1. Create, edit, and delete a talk

Based on these requirements we can assume we need the following for this application:

  1. Talk, Comment, and (optional) Report types
  2. Database
  3. GraphQL definition for mutations (create, update, delete talks, comments, and reports)
  4. GraphQL definition for queries
  5. GraphQL resolvers for all operations

To build this app, we could use the following annotated GraphQL schema:

type Talk @model
  @auth(rules: [{allow: groups, groups: ["Admin"], operations: [create, update, delete]}])
  {
  id: ID!
  name: String!
  speakerName: String!
  speakerBio: String!
  time: String
  timeStamp: String
  date: String
  location: String
  summary: String!
  twitter: String
  github: String
  speakerAvatar: String
  comments: [Comment] @connection(name: "TalkComments")
}

type Comment @model {
  id: ID!
  talkId: ID
  talk: Talk @connection(sortField: "createdAt", name: "TalkComments", keyField: "talkId")
  message: String
  createdAt: String
  createdBy: String
  deviceId: ID
}

type Report @model
  @auth(rules: [
    {allow: owner, operations: [create, update, delete]},
    {allow: groups, groups: ["Admin"]}
  ])
  {
  id: ID!
  commentId: ID!
  comment: String!
  talkTitle: String!
  deviceId: ID
}

type ModelCommentConnection {
  items: [Comment]
  nextToken: String
}

type Query {
  listCommentsByTalkId(talkId: ID!): ModelCommentConnection
}

type Subscription {
  onCreateCommentWithId(talkId: ID!): Comment
        @aws_subscribe(mutations: ["createComment"])
}

In this schema, notice we are adding an additional subscription to listen to new comments by ID. This way we can only subscribe to comments for the talk that we are currently viewing.

========================================

Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

Learn More

GraphQL with React: The Complete Developers Guide

The Modern GraphQL Bootcamp (with Node.js and Apollo)

Build a Realtime App with React Hooks and GraphQL

Full-Stack React with GraphQL and Apollo Boost

Curious Use Cases of GraphQL (and The Future of GraphQL)

Curious Use Cases of GraphQL (and The Future of GraphQL)

In this GraphQL tutorial, we’ll show how developers are using GraphQL as an API gateway to accomplish things that you may have never thought possible. Curious Use Cases of GraphQL (and The Future of GraphQL). As GraphQL moves into the mainstream, the tooling & ecosystem has grown and has made it possible to do much more with GraphQL than using it as just a data layer.

As GraphQL moves into the mainstream, the tooling & ecosystem has grown and has made it possible to do much more with GraphQL than using it as just a data layer. In this talk, I’ll show how developers are using GraphQL as an API gateway to accomplish things that you may have never thought possible.

More details:

When we think of GraphQL at the resolver level, we typically associate some type of database as the resolver data source, but in practice a resolver is simply a function. What this means is that we can do much more with our GraphQL APIs & our resolvers than we ever thought possible, including things like taking existing REST APIs & transforming them into GraphQL APIs (http resolvers), passing the query to Lambda or serverless functions for processing & returning the response via a GraphQL query (for things like AI & ML), geospatial & time-based queries (passing the query to Elasticsearch), & even VR & AR apps (passing in user location / app info & using the subscription to transmit image assets). In this talk, I’ll walk through what this looks like in theory & in practice, demoing 4 different applications that implement this functionality & showing the code that make the magic happen.