DEV Community

Cover image for Webhooks as GraphQL Subscriptions using GraphQL Mesh
TheGuildBot for The Guild

Posted on • Updated on • Originally published at the-guild.dev

Webhooks as GraphQL Subscriptions using GraphQL Mesh

This article was published on Monday, October 5, 2020 by Arda Tanrikulu @ The Guild Blog

GraphQL Mesh lets you query any data source and protocol with GraphQL by using powerful handlers
(Swagger/OpenAPI, gRPC, SOAP and others...) Today we are happy to announce that GraphQL Mesh now
allows you to consume your existing HTTP Webhooks as GraphQL Subscriptions!

Not only that, but you could extend the GraphQL Subscriptions result, so you could subscribe to a
webhook and get back an enriched data result, with data from other sources that don't have push
communication abilities.

And it's also possible even if your webhooks don't have any schema!

Let's see how to create a GraphQL Subscription from a Webhook, once without a schema and once
automatically from an OpenAPI schema.

We are already able to consume our existing REST APIs in GraphQL Mesh even if they don't have any
schema by using our JSON Schema Handler. See more

Add a New Field to Our Existing Configuration for an HTTP Webhook

In the following example configuration, we have a regular GraphQL Mesh configuration for schemaless
REST API.

sources:
  - name: Example
    handler:
      jsonSchema:
        baseUrl: http://localhost:4001
        operationHeaders:
          Content-Type: application/json
        operations:
          - type: Query
            field: todos
            path: /todos
            method: GET
            responseSample: ./todos.json
          - type: Mutation
            field: addTodo
            path: /todo
            method: POST
            requestSample: ./addTodo.json
            responseSample: ./todo.json
            responseTypeName: Todo
Enter fullscreen mode Exit fullscreen mode

Assume that we point our REST API to send HTTP requests to our Mesh server's /webhooks/todo_added
path, so we need to configure Mesh to listen to that path.

serve:
  port: 4000
  handlers:
    - path: /webhooks/todo_added
      pubsubTopic: todoAdded
Enter fullscreen mode Exit fullscreen mode

Under serve we define the port we want Mesh to listen to and add a handler in a declarative way
without a single line of code. pubsubTopic is the unique name for that webhook. This topic will
receive upcoming HTTP requests so that JSON Schema handler will consume it as a GraphQL
Subscription.

Let's define a new field under Subscription field under operations in the handler level;

operations:
  - type: Subscription
    field: todoAdded
    pubsubTopic: todoAdded
    responseSample: ./todo.json
Enter fullscreen mode Exit fullscreen mode

Now we have a todoAdded field that listens to a webhook through Mesh's PubSub instance and this
field has a return type generated based on todo.json sample response.

You can start mesh serve and start listening for that webhook by the following GraphQL operation;

subscription {
  todoAdded {
    id
    title
    content
  }
}
Enter fullscreen mode Exit fullscreen mode

You can find a complete working example on GitHub

Other Methods for Subscriptions Such as RabbitMQ or Kafka

It is possible to configure Mesh to handle other schemaless subscription solutions like RabbitMQ and
Kafka using JSON Schema handler but this is the topic of another blog post.

Generating GraphQL Subscriptions from OpenAPI Callbacks

Mesh can listen to webhooks through a PubSub engine easily. Mesh will generate the necessary typings
and subscriptions fields connected to your PubSub engine from the OpenAPI schema. You only need Mesh
to know what path the server should listen to like below;

sources:
  - name: OpenAPICallbackExample
    handler:
      openapi:
        source: ./openapi.yml
        baseUrl: http://localhost:4001

serve:
  port: 4000
  handlers:
    - path: /callback
      pubsubTopic: http://localhost:4000/callback
Enter fullscreen mode Exit fullscreen mode

In this example configuration, we assume that we have an API server running on 4001 port and it has
a webhook that will forward requests from /callback path to http://localhost:4000/callback topic
because OpenAPI Handler uses callback url as PubSub topic name. If you want to have a more
customized way of handling incoming webhook requests, you can always write your own Express handler
and define it instead of pubsubTopic. You will find Mesh's PubSub engine under the request
object as request.pubsub.

You can check
this example for more

Now You

We would love to hear your use cases and feedback to make Mesh better and more powerful! Feel free
to submit issues on GitHub to share your ideas or you can also join our community channel on
Discord!

Top comments (0)