flesh out the schema/types

This commit is contained in:
Evans Hauser 2018-04-20 16:30:02 -07:00
parent e3ea618788
commit 4cb76e89e1
No known key found for this signature in database
GPG key ID: 88AF586817F52EEC

View file

@ -3,89 +3,154 @@ title: Schema Types
description: How to write your types, expose your data, and keep it all working great
---
> (Jesse) I am proposing that types should be explained before queries, since a query is a type.
> (Evans) This could possibly be just a reference section, especially if the essentials section gives just enough info for someone to start writing resolvers. Honestly The only type necessary to start is String ;)
## Overview
GraphQL is a strongly typed language and the concept of "types" is a fundamental part of GraphQL. Types define the capabilities of a GraphQL server and allow GraphQL operations to be easily validated.
GraphQL is a strongly typed language and the concept of "types" is a fundamental part of GraphQL. Types define the capabilities of a GraphQL server and allow GraphQL operations to be validated.
While in the most basic sense, you could have a GraphQL server return a single, scalar type, combining these types provides the ability to build GraphQL servers of varying complexities.
## Core scalar types
The default, scalar types which GraphQL offers are:
Scalar types represent the leaves of an operation and alway resolve to concrete data. The default, scalar types which GraphQL offers are:
* `Int`
* `Float`
* `String`
* `Boolean`
* `ID` (a special type of `String`)
* `Int`: Signed 32bit integer
* `Float`: Signed double-precision floating-point value
* `String`: UTF8 character sequence
* `Boolean`: true or false
* `ID` (serialized as `String`): A unique identifier, often used to refetch an object or as the key for a cache. While serialized as a String, ID signifies that it is not intended to be humanreadable
These primitive types
These primitive types cover a majority of use cases. For other use cases, we can create [custom scalar types]().
## Object types
The object type is the most common type used in a schema and represents a group of fields. In turn, each field maps to another type, allowing nested types and circular references in a schema design.
The object type is the most common type used in a schema and represents a group of fields. Each field inside of an object type maps to another type, allowing nested types and circular references.
```graphql
type Query {
type TypeName {
fieldA: String
fieldB: Boolean
fieldC: Int
fieldD: CustomType
}
type CustomType {
circular: TypeName
}
```
### `Query` type
The `Query` type defines the entry points into Apollo server for fetching data. Since all requests must use one of the Query's fields, the Query serves as the organization point for defining how to access to other fields. It can be referred to as the root query type. This schema is an example of a server that can return a todo list for given user.
```graphql
type Query {
todos(user: ID): [String]
}
```
To write your first Query go [here]().
### `Mutation` type
The `Mutation` type or root mutation type defines the entry points into Apollo server for modifying server data. Similar to the `Query`, the root mutation type serves as the organization point for all requests designed to modify the server's data.
```graphql
type Response {
success: Boolean
error: Error
newTodo: String
}
type Query {
addTodo(user: ID, todo: String): Response
}
```
To implement your first mutation, follow the [... guide]().
### `Subscription` type
The `Subscription` type defines entry points into Apollo server for the advanced use case of listening to events over a persistent connection. For more information, see the subscription section.
## Enum type
The `Enum` type are a special type of scalar that is restricted to a set of values.
```graphql
enum Genre {
MYSTERY
SIFI
FANTASY
}
```
In Apollo server, a resolver that returns an enum can use the direct string representation.
```js
const schema = `
type Query {
genre: Genre
}
`;
const resolvers = {
Query: {
genre: () => 'MYSTERY'
}
}
```
## List type modifier
Lists are defined with as type modifier that wraps object types, scalars, and enums. This signals to Apollo server that the resolver should return an array of the wrapped type. In this example `todos` is expected to return a list of strings.
```js
const schema = `
type Query {
todos: [String]
}
`;
const resolvers = {
Query: {
todos: () => ['reduce', 'reuse', 'gc']
}
}
```
## Non-nullable types
By default, each of the core scalar types can also be null. That is to say, they can either return a value of the specified type or they can have no value.
By default, each of the core scalar types can also be null. That is to say, they can either return a value of the specified type or they can have no value. This default provides the maximum flexibility for schema changes and enables the errors to be returned at the finest granularity. The only time to make a field non-null is if an object cannot exist without the field.
In order to specify that a type _must_ be defined, an exclamation mark (`!`) can be appended to a type to ensure the presence of the value in return results. For example, a `String` which could not be missing a value would be identified as `String!`.
To override this default and specify that a type _must_ be defined, an exclamation mark (`!`) can be appended to a type to ensure the presence of the value in return results. For example, a `String` which could not be missing a value would be identified as `String!`. If the resolver for a non-nullable field throws an error, then the error is propagated up to the parents on the resolver chain until either the root field or a nullable field is reached.
By using the exclamation mark to declare a field as non-nullable, the contract with the client can be simplified since clients will not have to check to see whether a field contains a value or not.
On the other hand, marking fields as non-nullable might make it more difficult to iterate into a schema which makes a field optional, since existing client code would need to be made aware of this new requirement, and adjust their logic accordingly.
Using the exclamation mark to declare a field as non-nullable simplifies the contract with the client, since clients will not have to check to see whether a field contains a value or not. However marking fields as non-nullable means that the field will always be a part of that type, which make it impossible to deprecate from an active schema. Removing a nullability check from a field makes a field optional. Existing client code would need to be made aware of this new requirement, and adjust their logic accordingly.
## Union type
The `Union` type indicates that a field can return more than one object type, but doesn't define specific fields itself. Therefore, a query being made on a field which is union-typed must specify the object types containing the fields it wants.
## Enum type
```graphql
union Result = Book | Author
The `Enum` type
type Query {
search: [Result]
}
```
The query for these result would appear:
```graphql
{
search(contains: "") {
... on Book {
title
}
... on Author {
name
}
}
}
```
## `Query` type
The `Query` type is a special object type used to organize other fields.
* special type to define entry points to server to get data
* often called the root query type
* How to add arguments
* backed by a resolver, which is a function that provides the data requested by a query
* essential/queries for info on what queries look like from client/on server
* server/queries for details to implement them
## `Mutation` type
* special type to define operations to change server data
* backed by a resolver that performs the back-end modification
* look at essentials/mutations for mutation shape from client and appearance on server
* server/mutations for implementation information
## `Subscription` type
* special type to define operations that listen to events
* disclaimer that you'll want to setup your server with queries and mutations before adding in subscriptions
* backed by a resolver that calls `subscribe` or something 🤷‍♂️
* look at advanced/subscriptions for mutation shape from client and appearance on server and implementation information
For more information, see the subscription section
## Custom scalar types
The core types provide functionality for most of the common cases an application will have, but it's also possible to define custom types.
For more information, see the advanced section on [custom scalar types]().