Skip to content

Commit

Permalink
GraphQL Tools v5.0.0 (#1308)
Browse files Browse the repository at this point in the history
Co-authored-by: Yaacov Rydzinski <yaacovCR@gmail.com>
Co-authored-by: Adam Lovatt <jalovatt@hotmail.com>
Co-authored-by: Dale Seo <dale.seo@gmail.com>
Co-authored-by: Hugh Willson <hugh@octonary.com>
Co-authored-by: David Marvasti <david.marvasti@wework.com>
Co-authored-by: Daniel Schmidt <danielmschmidt92@gmail.com>
  • Loading branch information
7 people committed Apr 14, 2020
1 parent fba7f69 commit 1d5a9bd
Show file tree
Hide file tree
Showing 217 changed files with 18,974 additions and 9,148 deletions.
508 changes: 508 additions & 0 deletions .eslintrc.yml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
17 changes: 12 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
node_modules
coverage
npm-debug.log
dist
node_modules/
coverage/
dist/

*.tgz
.DS_Store
package-lock.json

yarn.lock
package-lock.json

npm-debug.log*
yarn-debug.log*
yarn-error.log*

.eslintcache
9 changes: 0 additions & 9 deletions .npmignore

This file was deleted.

1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
save-exact = true
20 changes: 15 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,26 @@ node_js:
- "10"
- "12"

env:
- GRAPHQL_VERSION='legacy'
- GRAPHQL_VERSION='latest'

install:
- npm config set spin=false
- npm install -g coveralls
- npm install

script:
- npm test
- npm run lint
- npm run coverage
- coveralls < ./coverage/lcov.info || true # if coveralls doesn't have it covered
- if [[ $GRAPHQL_VERSION == "latest" ]]; then
npm run lint;
fi
- if [[ $GRAPHQL_VERSION == "latest" ]]; then
npm run format:check;
fi
- npm run compile
- if [[ $GRAPHQL_VERSION == "legacy" ]]; then
npm install graphql@0.13;
fi
- npm run test

# Allow Travis tests to run in containers.
sudo: false
1 change: 0 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"node_modules": true,
"test-lib": true,
"lib": true,
"dist": true,
"coverage": true,
"npm": true
},
Expand Down
384 changes: 217 additions & 167 deletions CHANGELOG.md

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

[![npm version](https://badge.fury.io/js/graphql-tools.svg)](https://badge.fury.io/js/graphql-tools)
[![Build Status](https://travis-ci.org/apollographql/graphql-tools.svg?branch=master)](https://travis-ci.org/apollographql/graphql-tools)
[![Coverage Status](https://coveralls.io/repos/github/apollographql/graphql-tools/badge.svg?branch=master)](https://coveralls.io/github/apollographql/graphql-tools?branch=master)
[![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](http://www.apollostack.com/#slack)
[![Discord Chat](https://img.shields.io/discord/625400653321076807)](https://discord.gg/xud7bH9)

This package provides a few useful ways to create a GraphQL schema:

Expand Down Expand Up @@ -121,5 +120,5 @@ Contributions, issues and feature requests are very welcome. If you are using th

## Maintainers

- [@hwillson](https://github.com/hwillson) (Apollo)
- [@benjamn](https://github.com/benjamn) (Apollo)
- [@yaacovCR](https://github.com/yaacovCR)
- [@kamilkisiela](https://github.com/kamilkisiela) ([The Guild](https://github.com/the-guild-org))
6 changes: 3 additions & 3 deletions designs/connectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This document is intended as a design document for people who want to write conn
This is a draft at the moment, and not the final document. Chances are that the spec will change as we learn about the better ways to build GraphQL servers. It should be pretty close to the final version though, so if you want to get started and build connectors for specific backends, this document is a good starting point.


Technically you could write a GraphQL server without connectors and models by writing all your logic directly into the resolve functions, but in most cases that's not ideal. Connectors and models are a way of organizing code in a GraphQL server, and you should use them to keep your server modular. If the need arises, you can always write optimized queries directly in your resolvers or models.
Technically you could write a GraphQL server without connectors and models by writing all your logic directly into the resolvers, but in most cases that's not ideal. Connectors and models are a way of organizing code in a GraphQL server, and you should use them to keep your server modular. If the need arises, you can always write optimized queries directly in your resolvers or models.

Let's use an example schema, because it's always easier to explain things with examples:
```
Expand Down Expand Up @@ -60,7 +60,7 @@ Both batching and caching are more important in GraphQL than in traditional endp

Models are the glue between connectors - which are backend-specific - and GraphQL types - which are app-specific. They are very similar to models in ORMs, such as Rails' Active Record.

Let's say for example that you have two types, Author and Post, which are both stored in MySQL. Rather than calling the MySQL connector directly from your resolve functions, you should create models for Author and Post, which use the MySQL connector. This additional level of abstraction helps separate the data fetching logic from the GraphQL schema, which makes reusing and refactoring it easier.
Let's say for example that you have two types, Author and Post, which are both stored in MySQL. Rather than calling the MySQL connector directly from your resolvers, you should create models for Author and Post, which use the MySQL connector. This additional level of abstraction helps separate the data fetching logic from the GraphQL schema, which makes reusing and refactoring it easier.

In the example schema above, the Authors model would have the following methods:
```
Expand Down Expand Up @@ -150,7 +150,7 @@ app.use('/graphql', apolloServer({
});
```

Step 4: Calling models in resolve functions
Step 4: Calling models in resolvers
```
function resolve(author, args, ctx){
return ctx.models.Author.getById(author.id, ctx);
Expand Down
6 changes: 3 additions & 3 deletions designs/graphql-decorator-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ Decorators can be selectively applied to:
* A specific field
* An argument

Decorators can modify the behavior of the parts of the schema they are applied to. Sometimes that requires modifying other parts of the schema. For instance, the @validateRange decorator modifies the behavior of the containing field's resolve function.
Decorators can modify the behavior of the parts of the schema they are applied to. Sometimes that requires modifying other parts of the schema. For instance, the @validateRange decorator modifies the behavior of the containing field's resolver.

In general, decorators either add, remove or modify an attribute of the thing they wrap. The most common type of decorator (e.g. @adminOnly, @log, @connector) will wrap one or more field's resolve functions to alter the execution behavior of the GraphQL schema, but other decorators (e.g. @description) may add attributes to a type, field or argument. It is also possible for a type decorator to add a field to the type (e.g. @id(fields: ["uuid"]) can add the __id field).
In general, decorators either add, remove or modify an attribute of the thing they wrap. The most common type of decorator (e.g. @adminOnly, @log, @connector) will wrap one or more field resolvers to alter the execution behavior of the GraphQL schema, but other decorators (e.g. @description) may add attributes to a type, field or argument. It is also possible for a type decorator to add a field to the type (e.g. @id(fields: ["uuid"]) can add the __id field).


## Schema decorator API
Expand Down Expand Up @@ -120,7 +120,7 @@ class SampleFieldDecorator extends SchemaDecorator {
return (wrappedThing, { schema, type, field, context }) => {
// use this.config ...
// use args
// modify wrappedThing's properties, resolve functions, etc.
// modify wrappedThing's properties, resolvers, etc.
}
}
}
Expand Down
20 changes: 10 additions & 10 deletions docs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"dependencies": {
"gatsby": "2.20.18",
"gatsby-theme-apollo-docs": "4.1.4",
"react": "16.12.0",
"react-dom": "16.12.0"
"react": "16.13.1",
"react-dom": "16.13.1"
}
}
9 changes: 0 additions & 9 deletions docs/source/connectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,3 @@ You can improve the situation by adding a per-request cache with `dataloader`, F
### One dataloader per request

One important thing to understand about `dataloader` is that it caches the results forever, unless told otherwise. So we really want to make sure we create a new instance for _every_ request sent to our server, so that we de-duplicate fetches in one query but not across multiple requests or, even worse, multiple users.

At this point, the code becomes a bit more complex, so we won't reproduce it here. Check out the GitHunt-API example for the details:

1. The [GitHub connector](https://github.com/apollostack/GitHunt-API/blob/cc67a4506c31310b4ba8d811dda11d258c7d60d6/api/github/connector.js), which uses DataLoader, passes along API keys, and does extra caching with GitHub's eTag feature.
2. The [GitHub model](https://github.com/apollostack/GitHunt-API/blob/cc67a4506c31310b4ba8d811dda11d258c7d60d6/api/github/models.js), which defines some helpful functions to fetch users and repositories.
3. The [GraphQL context](https://github.com/apollostack/GitHunt-API/blob/cc67a4506c31310b4ba8d811dda11d258c7d60d6/api/index.js#L67-L73), which includes the models, initialized with the connector for every request.
4. The [resolvers](https://github.com/apollostack/GitHunt-API/blob/cc67a4506c31310b4ba8d811dda11d258c7d60d6/api/sql/schema.js#L63), which use the model from the context to actually fetch the object.

The code is more decoupled than necessary for a small example, but it's done that way intentionally to demonstrate how a larger API could be laid out.
2 changes: 0 additions & 2 deletions docs/source/directive-resolvers.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
## Directive example

Let's take a look at how we can create `@upper` Directive to upper-case a string returned from resolve on Field
[See a complete runnable example on Launchpad.](https://launchpad.graphql.com/p00rw37qx0)

To start, let's grab the schema definition string from the `makeExecutableSchema` example [in the "Generating a schema" article](/generate-schema/#example).

Expand Down Expand Up @@ -65,7 +64,6 @@ graphql(schema, query).then((result) => console.log('Got result', result));
## Multi-Directives example

Multi-Directives on a field will be apply with LTR order.
[See a complete runnable example on Launchpad.](https://launchpad.graphql.com/nx945rq1x7)

```js
// graphql-tools combines a schema string with resolvers.
Expand Down
47 changes: 35 additions & 12 deletions docs/source/generate-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ The graphql-tools package allows you to create a GraphQL.js GraphQLSchema instan

## Example

[See the complete live example in Apollo Launchpad.](https://launchpad.graphql.com/1jzxrj179)

When using `graphql-tools`, you describe the schema as a GraphQL type language string:

```js
Expand Down Expand Up @@ -132,6 +130,31 @@ const typeDefs = [`
`]
```

If one of the types extended needs a resolver you can use `makeExecutableSchema` like this:

```js
const barsResolver = {
Query: {
bars(parent, args, context, info) {
// ...
}
}
};

const foosResolver = {
Query: {
foos(parent, args, context, info) {
// ...
}
}
}

const schema = makeExecutableSchema({
typeDefs,
resolvers: [barsResolver, foosResolver]
})
```

## Learning the GraphQL schema language

The official documentation on graphql.org now has [a section about GraphQL schemas](http://graphql.org/learn/schema/) which explains all of the different schema features and how to use them with the schema language.
Expand Down Expand Up @@ -195,31 +218,31 @@ const jsSchema = makeExecutableSchema({
typeDefs,
resolvers, // optional
logger, // optional
allowUndefinedInResolve = false, // optional
resolverValidationOptions = {}, // optional
directiveResolvers = null, // optional
schemaDirectives = null, // optional
parseOptions = {}, // optional
inheritResolversFromInterfaces = false // optional
allowUndefinedInResolve: false, // optional
resolverValidationOptions: {}, // optional
directiveResolvers: null, // optional
schemaDirectives: null, // optional
parseOptions: {}, // optional
inheritResolversFromInterfaces: false // optional
});
```

- `typeDefs` is a required argument and should be an GraphQL schema language string or array of GraphQL schema language strings or a function that takes no arguments and returns an array of GraphQL schema language strings. The order of the strings in the array is not important, but it must include a schema definition.

- `resolvers` is an optional argument _(empty object by default)_ and should be an object that follows the pattern explained in [article on resolvers](/resolvers/).
- `resolvers` is an optional argument _(empty object by default)_ and should be an object or an array of objects that follow the pattern explained in [article on resolvers](/resolvers/)

- `logger` is an optional argument, which can be used to print errors to the server console that are usually swallowed by GraphQL. The `logger` argument should be an object with a `log` function, eg. `const logger = { log: e => console.log(e) }`

- `parseOptions` is an optional argument which allows customization of parse when specifying `typeDefs` as a string.

- `allowUndefinedInResolve` is an optional argument, which is `true` by default. When set to `false`, causes your resolve functions to throw errors if they return undefined, which can help make debugging easier.
- `allowUndefinedInResolve` is an optional argument, which is `true` by default. When set to `false`, causes your resolver to throw errors if they return undefined, which can help make debugging easier.

- `resolverValidationOptions` is an optional argument which accepts an `ResolverValidationOptions` object which has the following boolean properties:
- `requireResolversForArgs` will cause `makeExecutableSchema` to throw an error if no resolve function is defined for a field that has arguments.
- `requireResolversForArgs` will cause `makeExecutableSchema` to throw an error if no resolver is defined for a field that has arguments.

- `requireResolversForNonScalar` will cause `makeExecutableSchema` to throw an error if a non-scalar field has no resolver defined. Setting this to `true` can be helpful in catching errors, but defaults to `false` to avoid confusing behavior for those coming from other GraphQL libraries.

- `requireResolversForAllFields` asserts that *all* fields have a valid resolve function.
- `requireResolversForAllFields` asserts that *all* fields have valid resolvers.

- `requireResolversForResolveType` will require a `resolveType()` method for Interface and Union types. This can be passed in with the field resolvers as `__resolveType()`. False to disable the warning.

Expand Down
4 changes: 2 additions & 2 deletions docs/source/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ title: graphql-tools
description: A set of utilities to build your JavaScript GraphQL schema in a concise and powerful way.
---

GraphQL Tools is an npm package and an opinionated structure for how to build a GraphQL schema and resolvers in JavaScript, following the GraphQL-first development workflow.
GraphQL Tools is an npm package and an opinionated structure for how to build a GraphQL schema and resolvers in JavaScript, following the GraphQL-first development workflow, authored originally by the Apollo team.

```txt
npm install graphql-tools graphql
```

Functions in the `graphql-tools` package are not just useful for building servers. They can also be used in the browser, for example to mock a backend during development or testing.
Functions in the `graphql-tools` packages are not just useful for building servers. They can also be used in the browser, for example to mock a backend during development or testing.

Even though we recommend a specific way of building GraphQL servers, you can use these tools even if you don't follow our structure; they work with any GraphQL-JS schema, and each tool can be useful on its own.

Expand Down

0 comments on commit 1d5a9bd

Please sign in to comment.