All Projects β†’ contentful-graveyard β†’ Cf Graphql

contentful-graveyard / Cf Graphql

Generate a GraphQL schema out of your Contentful space

Programming Languages

javascript
184084 projects - #8 most used programming language

Labels

Projects that are alternatives of or similar to Cf Graphql

Prisma Examples
πŸš€ Ready-to-run Prisma example projects
Stars: ✭ 3,017 (+1513.37%)
Mutual labels:  graphql
Graphql Faker
🎲 Mock or extend your GraphQL API with faked data. No coding required.
Stars: ✭ 2,361 (+1162.57%)
Mutual labels:  graphql
Json To Simple Graphql Schema
Transforms JSON input into a GraphQL schema
Stars: ✭ 185 (-1.07%)
Mutual labels:  graphql
Fullstack Boilerplate
Fullstack boilerplate using Typescript, React, GraphQL
Stars: ✭ 181 (-3.21%)
Mutual labels:  graphql
Gqlify
[NOT MAINTAINED]An API integration framework using GraphQL
Stars: ✭ 182 (-2.67%)
Mutual labels:  graphql
Prisma Auth0 Example
Boilerplate Prisma Startup
Stars: ✭ 184 (-1.6%)
Mutual labels:  graphql
React Auth App Example
An app example with authentication using Create React App, React, React Router, Apollo, GraphQL, Redux and Redux Form.
Stars: ✭ 179 (-4.28%)
Mutual labels:  graphql
Fullstack
React/ApolloGraphQL/Node/Mongo demo written in Typescript
Stars: ✭ 12,653 (+6666.31%)
Mutual labels:  graphql
React Conf 17 Videos
Find that one presentation you missed!
Stars: ✭ 182 (-2.67%)
Mutual labels:  graphql
Graphql Ppx
GraphQL language primitives for ReScript/ReasonML written in ReasonML
Stars: ✭ 185 (-1.07%)
Mutual labels:  graphql
Examples
Examples for GraphQL.NET
Stars: ✭ 179 (-4.28%)
Mutual labels:  graphql
Graphql2rest
GraphQL to REST converter: automatically generate a RESTful API from your existing GraphQL API
Stars: ✭ 181 (-3.21%)
Mutual labels:  graphql
Hotchocolate
Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Banana Cake Pop the awesome Monaco based GraphQL IDE.
Stars: ✭ 3,009 (+1509.09%)
Mutual labels:  graphql
Venia
Clojure(Script) graphql query generation
Stars: ✭ 179 (-4.28%)
Mutual labels:  graphql
Next React Graphql Apollo Hooks
React, Apollo, Next.js, GraphQL, Node.js, TypeScript high performance boilerplate with React hooks GraphQL implementation and automatic static type generation
Stars: ✭ 186 (-0.53%)
Mutual labels:  graphql
Storefront Api
Storefront GraphQL API Gateway. Modular architecture. ElasticSearch included. Works great with Magento1, Magento2, Spree, OpenCart, Pimcore and custom backends
Stars: ✭ 180 (-3.74%)
Mutual labels:  graphql
Comunica
πŸ“¬ A knowledge graph querying framework for JavaScript
Stars: ✭ 183 (-2.14%)
Mutual labels:  graphql
Gatsby Starter Morning Dew
πŸš€ A Gatsby theme/starter to build lightning-fast blog/websites
Stars: ✭ 186 (-0.53%)
Mutual labels:  graphql
Apollo Offline
An offline toolkit for the Apollo client
Stars: ✭ 186 (-0.53%)
Mutual labels:  graphql
Smakosh.com
My personal website
Stars: ✭ 185 (-1.07%)
Mutual labels:  graphql

cf-graphql

travis build status npm version npm downloads deps status dev deps status codecov coverage

cf-graphql is a library that allows you to query your data stored in Contentful with GraphQL. A schema and value resolvers are automatically generated out of an existing space.

Generated artifacts can be used with any node-based GraphQL server. The outcome of the project's main function call is an instance of the GraphQLSchema class.

Table of contents

Disclaimers

Please note that cf-graphql library is released as an experiment:

  • we might introduce breaking changes into programmatic interfaces and space querying approach before v1.0 is released
  • there’s no magic bullet: complex GraphQL queries can result in a large number of CDA calls, which will be counted against your quota
  • we might discontinue development of the library and stop maintaining it

First steps

If you just want to see how it works, please follow the Demo section. You can deploy the demo with your own credentials so it queries your own data.

In general cf-graphql is a library and it can be used as a part of your project. If you want to get your hands dirty coding, follow the Programmatic usage section.

Demo

We host an online demo for you. You can query Contentful's "Blog" space template there. This how its graph looks like:

Demo space graph

Run it locally

This repository contains a demo project. The demo comes with a web server (with CORS enabled) providing the GraphQL, an in-browser IDE (GraphiQL) and a React Frontend application using this endpoint.

To run it, clone the repository, install dependencies and start a server:

git clone [email protected]:contentful-labs/cf-graphql.git
cd cf-graphql/demo
# optionally change your node version with nvm, anything 6+ should work just fine
# we prefer node v6 matching the current AWS Lambda environment
nvm use
npm install
npm start

Use http://localhost:4000/graphql/ to query the data from within your application and navigate to http://localhost:4000 to use the IDE (GraphiQL) for test-querying. Please refer to the Querying section for more details.

If you also want to see how to integrate GraphQL in a React technology stack the demo project also contains an application based on the Apollo framework. To check it out use http://localhost:4000/client/.

To use your own Contentful space with the demo, you have to provide:

  • space ID
  • CDA token
  • CMA token

Please refer the "Authentication" section of Contentful's documentation.

You can provide listed values with env variables:

SPACE_ID=some-space-id CDA_TOKEN=its-cda-token CMA_TOKEN=your-cma-token npm start

Deploy to Zeit's now

To be able to deploy to Zeit's now you need to have an activated account. There is a free open source option available.

You can also deploy the demo with now. In your terminal, navigate to the demo/ directory and run:

npm run deploy-demo-now

As soon as the deployment is done you'll have a URL of your GraphQL server copied.

You can also create a deployment for your own space:

SPACE_ID=some-space-id CDA_TOKEN=its-cda-token CMA_TOKEN=your-cma-token npm run deploy-now

Please note:

  • when deploying a server to consume Contentful's "Blog" space template, the command to use is npm run deploy-demo-now; when the demo should be configured to use your own space, the command is npm run deploy-now
  • if you've never used now before, you'll be asked to provide your e-mail; just follow on-screen instructions
  • if you use now's OSS plan (the default one), the source code will be public; it's completely fine: all credentials are passed as env variables and are not available publicly

Programmatic usage

The library can be installed with npm:

npm install --save cf-graphql

Let's assume we've required this module with const cfGraphql = require('cf-graphql'). To create a schema out of your space you need to call cfGraphgl.createSchema(spaceGraph).

What is spaceGraph? It is a graph-like data structure containing descriptions of content types of your space which additionally provide some extra pieces of information allowing the library to create a GraphQL schema.

To prepare this data structure you need to fetch raw content types data from the CMA. Let's create a Contentful client first:

const client = cfGraphql.createClient({
  spaceId: 'some-space-id',
  cdaToken: 'its-cda-token',
  cmaToken: 'your-cma-token'
});

spaceId, cdaToken and cmaToken options are required. You can also pass the following options:

  • locale - a locale code to use when fetching content. If not provided, the default locale of a space is used
  • preview - if true, CPA will be used instead of CDA for fetching content
  • cpaToken - if preview is true then this option has to hold a CPA token

Fetch content types with your client and then pass them to cfGraphql.prepareSpaceGraph(rawCts):

client.getContentTypes()
.then(cfGraphql.prepareSpaceGraph)
.then(spaceGraph => {
  // `spaceGraph` can be passed to `cfGraphql.createSchema`!
});

The last step is to use the schema with a server. A popular choice is express-graphql. The only caveat is how the context is constructed. The library expects the entryLoader key of the context to be set to an instance created with client.createEntryLoader():

// Skipped in snippet: `require` calls, Express app setup, `client` creation.
// `spaceGraph` was fetched and prepared in the previous snippet. In most cases
// you shouldn't be doing it per request, once is fine.
const schema = cfGraphql.createSchema(spaceGraph);

// IMPORTANT: we're passing a function to `graphqlHTTP`: this function will be
// called every time a GraphQL query arrives to create a fresh entry loader.
// You can also use `expressGraphqlExtension` described below.
app.use('/graphql', graphqlHTTP(function () {
  return {
    schema,
    context: {entryLoader: client.createEntryLoader()}
  };
}));

You can see a fully-fledged example in the demo/ directory.

Querying

For each Contentful content type three root-level fields are created:

  • a singular field accepts a required id argument and resolves to a single entity
  • a collection field accepts an optional q, skip and limit arguments and resolves to a list of entities
  • a collection metadata field accepts an optional q argument and resolves to a metadata object (currently comprising only count)

Please note that:

  • the q argument is a query string you could use with the CDA
  • both skip and limit arguments can be used to fetch desired page of results
    • skip defaults to 0
    • limit defaults to 50 and cannot be greater than 1000
  • some query string parameters cannot be used:
    • skip, limit - use collection field arguments instead
    • include, content_type - no need for them, the library will determine and use appropriate values internally
    • locale - all the content is fetched for a single locale. By default the default locale is used; alternate locale can be selected with the locale configuration option of cfGraphql.createClient

Assuming you've got two content types named post and author with listed fields, this query is valid:

{
  authors {
    name
  }

  authors(skip: 10, limit: 10) {
    title
    rating
  }

  _authorsMeta {
    count
  }

  posts(q: "fields.rating[gt]=5") {
    title
    rating
  }

  _postsMeta(q: "fields.rating[gt]=5") {
    count
  }

  post(id: "some-post-id") {
    title
    author
    comments
  }
}

Reference fields will be resolved to:

  • a specific type, if there is a validation that allows only entries of some specific content type to be linked
  • the EntryType, if there is no such constraint. The EntryType is an interface implemented by all the specific types

Example where the author field links only entries of one content type and the related field links entries of multiple content types:

{
  posts {
    author {
      name
      website
    }

    related {
      ... on Tag {
        tagName
      }
      ... on Place {
        location
        name
      }
    }
  }
}

Backreferences (backrefs) are automatically created for links. Assume our post content type links to the author content type via a field named author. Getting an author of a post is easy, getting a list of posts by an author is not. _backrefs mitigate this problem:

{
  authors {
    _backrefs {
      posts__via__author {
        title
      }
    }
  }
}

When using backreferences, there is a couple of things to keep in mind:

  • backrefs may be slow; always test with a dataset which is comparable with what you've got in production
  • backrefs are generated only when a reference field specifies a single allowed link content type
  • _backrefs is prefixed with a single underscore
  • __via__ is surrounded with two underscores; you can read this query out loud like this: "get posts that link to author via the author field"

Helpers

cf-graphql comes with helpers that help you with the cf-graphql integration. These are used inside of the demo application.

expressGraphqlExtension

expressGraphqlExtension is a simple utility producing a function that can be passed directly to the express-graphql middleware.

// Skipped in this snippet: client and space graph creation
const schema = cfGraphql.createSchema(spaceGraph);

const opts = {
  // display the current cf-graphql version in responses
  version: true,
  // include list of the underlying Contentful CDA calls with their timing
  timeline: true,
  // display detailed error information
  detailedErrors: true
};

const ext = cfGraphql.helpers.expressGraphqlExtension(client, schema, opts);
app.use('/graphql', graphqlHTTP(ext));

Important: Most likely don't want to enable timeline and detailedErrors in your production environment.

graphiql

If you want to run your own GraphiQL and don't want to rely on the one shipping with e.g. express-graphql then you could use the graphiql helper.

const ui = cfGraphql.helpers.graphiql({title: 'cf-graphql demo'});
app.get('/', (_, res) => res.set(ui.headers).status(ui.statusCode).end(ui.body));

Contributing

Issue reports and PRs are more than welcomed.

License

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].