Back to Prisma1

graphql-binding

docs/1.12/06-GraphQL-Ecosystem/02-GraphQL-Binding/01-GraphQL-Binding.md

1.34.125.3 KB
Original Source

graphql-binding

šŸ”— graphql-binding is a package that simplifies the process of creating your own GraphQL bindings. GraphQL bindings are modular building blocks that allow to embed existing GraphQL APIs into your own GraphQL server. Think about it as turning (parts of) GraphQL APIs into reusable LEGO building blocks.

The idea of GraphQL bindings is introduced in detail in this blog post: Reusing & Composing GraphQL APIs with GraphQL Bindings

Install

sh
yarn add graphql-binding

API

Binding

constructor

ts
constructor(options: BindingOptions): Binding

BindingOptions has the following properties:

KeyRequiredTypeDefaultNote
schemaYesGraphQLSchema-The executable GraphQL schema for binding
fragmentReplacementsNoFragmentReplacements{}A list of GraphQL fragment definitions, specifying fields that are required for the resolver to function correctly
beforeNo() => void(() => undefined)A function that will be executed before a query/mutation is sent to the GraphQL API
handlerNoanynullThe handler object from JS Proxy
subscriptionHandlerNoanynull...

query & mutation

ts
binding.query.<rootField>: QueryMap<any> // where <rootField> is the name of a field on the Query type in the mapped GraphQL schema
binding.mutation.<rootField>: QueryMap<any> // where <rootField> is the name of a field on the Mutation type in the mapped GraphQL schema

A binding object exposes two properties which can be used to send queries and mutations to the API: binding.query and binding.mutation.

Both are of type QueryMap and will expose methods that are named after the schema's root fields on the Query and Mutation types.

These methods take three arguments:

NameRequiredTypeNote
argsNo[key: string]: anyAn object that contains the arguments of the root field
contextNo[key: string]: anyThe context object that's passed down the GraphQL resolver chain; every resolver can read from and write to that object
infoNoGraphQLResolveInfo | stringThe info object (which contains an AST of the incoming query/mutation) that's passed down the GraphQL resolver chain or a string containing a selection set
Example

Assume the following schema:

graphql
type Query {
  user(id: ID!): User
}

type Mutation {
  createUser(): User!
}

If there is a binding for a GraphQL API that implements this schema, you can invoke the following methods on it:

js
binding.query.user({ id: 'abc' })
binding.mutation.createUser()

When using the binding in a resolver implementation, it can be used as follows:

js
findUser(parent, args, context, info) {
  return binding.user({ id: args.id }, context, info)
}

newUser(parent, args, context, info) {
  return binding.createUser({}, context, info)
}

subscription

ts
binding.subscription.<rootField>(...):  AsyncIterator<any> | Promise<AsyncIterator<any>> // where <rootField> is the name of a field on the Subscription type in the mapped GraphQL schema

The binding.subscription property follows the same idea as query and mutation, but rather than returning a single value using a Promise, it returns a stream of values using AsyncIterator.

It is of type SubscriptionMap and will expose methods that are named after the schema's root fields on the Subscription type.

These methods take same three arguments as the generated methods on query and mutation, see above for the details.

Examples

Minimal example

js
const { makeExecutableSchema } = require('graphql-tools')
const { Binding } = require('graphql-binding')

const users = [
  {
    name: 'Alice',
  },
  {
    name: 'Bob',
  },
]

const typeDefs = `
  type Query {
    findUser(name: String!): User
  }
  type User {
    name: String!
  }
`

const resolvers = {
  Query: {
    findUser: (parent, { name }) => users.find(u => u.name === name),
  },
}

const schema = makeExecutableSchema({ typeDefs, resolvers })

const findUserBinding = new Binding({
  schema,
})

findUserBinding.findUser({ name: 'Bob' })
  .then(result => console.log(result))

Public GraphQL bindings

You can find practical, production-ready examples here:

Note: If you've created your own GraphQL binding based on this package, please add it to this list via a PR šŸ™Œ

If you have any questions, share some ideas or just want to chat about GraphQL bindings, join the #graphql-bindings channel in our Slack.