Skip to content
GraphQL example using Context & Services
JavaScript
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src
.gitignore
.prettierrc
README.md
graphql-context-services.flat.png
graphql-context-services.png
package.json
sandbox.config.json
yarn.lock

README.md

GraphQL Context and Services

Simple example showing how to use Context as a class within GraphQL, along with context.services for abstracting away downstream API complexity.

For extra credit, this also shows off Apollo's REST Data Source with built in caching!

Demo

Example of a GraphQL query

Use the following example query:

query MyGitHubRateLimit {
  # Example of getting properties from context
  ip

  # Example of using context.services.GitHub
  github {
    rateLimit {
      limit
      # 👇 Cached automatically!
      remaining
    }
  }

  # Returning the app version is handy 🤷‍♂️
  version
}

Rationale

  • Using Context (instead of a plain {...} object) moves complexity from within your middleware to a separate, testable layer:

    .use(
      "/graphql",
      graphql((req, res) => {
        const context = new Context({ req })
    
        return {
          context,
          graphiql: true,
          pretty: true,
          schema,
        }
      })
  • Context can have a strict, testable API for your resolvers to use, instead of ad-hoc reliance on req.query or req.body:

    // Before
    ip: (parent, args, context, info) => {
      if (req.header("x-forwarded-for")) {
        return req
          .header("x-forwarded-for")
          .split(",")
          .shift()
      }
    
      if (req.connection.remoteAddress) {
        return req.connection.remoteAddress
      }
    
      return req.ip
    }
    
    // After
    ip: (parent, args, context, inf0) => {
      return context.ip
    }
  • API calls within resolvers are simplified:

    rateLimit: (parent, args, context, info) => {
      const { GitHub } = context.services
    
      return GitHub.getRateLimit()
    }
  • The same as Apollo's dataSources, but works with the standard express-graphql library:

    https://www.apollographql.com/docs/apollo-server/features/data-sources.html#Accessing-data-sources-from-resolvers

Author

Eric Clemmons (@ericclemmons)

You can’t perform that action at this time.