GraphQL API
We recently improved this API so it’s easier to program and reason about. If you were using it prior to August 17th 2021, read this guide for info on how to upgrade.
Keystone generates a CRUD (create, read, update, delete) GraphQL API based on the schema definition provided in the system config.
Consider the following system definition:
import { config, list } from '@keystone-next/keystone';import { text } from '@keystone-next/keystone/fields';export default config({lists: {User: list({ fields: { name: text() } }),},/* ... */});
This system will generate the following GraphQL API.
Note: The names and types of the generated queries and mutations are based on the names of the lists and fields in the system config.
type Query {users(where: UserWhereInput! = {}orderBy: [UserOrderByInput!]! = []take: Intskip: Int! = 0): [User!]user(where: UserWhereUniqueInput!): UserusersCount(where: UserWhereInput! = {}): Int}type User {id: ID!name: String}input UserWhereUniqueInput {id: ID}input UserWhereInput {AND: [UserWhereInput!]OR: [UserWhereInput!]NOT: [UserWhereInput!]id: IDFiltername: StringNullableFilter}input IDFilter {equals: IDin: [ID!]notIn: [ID!]lt: IDlte: IDgt: IDgte: IDnot: IDFilter}input StringNullableFilter {equals: Stringin: [String!]notIn: [String!]lt: Stringlte: Stringgt: Stringgte: Stringcontains: StringstartsWith: StringendsWith: Stringmode: QueryModenot: NestedStringNullableFilter}enum QueryMode {defaultinsensitive}input NestedStringNullableFilter {equals: Stringin: [String!]notIn: [String!]lt: Stringlte: Stringgt: Stringgte: Stringcontains: StringstartsWith: StringendsWith: Stringnot: NestedStringNullableFilter}input UserOrderByInput {id: OrderDirectionname: OrderDirection}enum OrderDirection {ascdesc}type Mutation {createUser(data: UserCreateInput!): UsercreateUsers(data: [UserCreateInput!]!): [User]updateUser(where: UserWhereUniqueInput!, data: UserUpdateInput!): UserupdateUsers(data: [UserUpdateArgs!]!): [User]deleteUser(where: UserWhereUniqueInput!): UserdeleteUsers(where: [UserWhereUniqueInput!]!): [User]}input UserUpdateInput {name: String}input UserUpdateArgs {where: UserWhereUniqueInput!data: UserUpdateInput!}input UserCreateInput {name: String}
Queries
user
type Query {user(where: UserWhereUniqueInput!): User}type User {id: ID!name: String}input UserWhereUniqueInput {id: ID}
users
type Query {users(where: UserWhereInput! = {}orderBy: [UserOrderByInput!]! = []take: Intskip: Int! = 0): [User!]}type User {id: ID!name: String}input UserWhereInput {AND: [UserWhereInput!]OR: [UserWhereInput!]NOT: [UserWhereInput!]id: IDFiltername: StringNullableFilter}input IDFilter {equals: IDin: [ID!]notIn: [ID!]lt: IDlte: IDgt: IDgte: IDnot: IDFilter}input StringNullableFilter {equals: Stringin: [String!]notIn: [String!]lt: Stringlte: Stringgt: Stringgte: Stringcontains: StringstartsWith: StringendsWith: Stringmode: QueryModenot: NestedStringNullableFilter}enum QueryMode {defaultinsensitive}input NestedStringNullableFilter {equals: Stringin: [String!]notIn: [String!]lt: Stringlte: Stringgt: Stringgte: Stringcontains: StringstartsWith: StringendsWith: Stringnot: NestedStringNullableFilter}input UserOrderByInput {id: OrderDirectionname: OrderDirection}enum OrderDirection {ascdesc}
usersCount
type Query {usersCount(where: UserWhereInput! = {}): Int}input UserWhereInput {AND: [UserWhereInput!]OR: [UserWhereInput!]NOT: [UserWhereInput!]id: IDFiltername: StringNullableFilter}input IDFilter {equals: IDin: [ID!]notIn: [ID!]lt: IDlte: IDgt: IDgte: IDnot: IDFilter}input StringNullableFilter {equals: Stringin: [String!]notIn: [String!]lt: Stringlte: Stringgt: Stringgte: Stringcontains: StringstartsWith: StringendsWith: Stringmode: QueryModenot: NestedStringNullableFilter}enum QueryMode {defaultinsensitive}input NestedStringNullableFilter {equals: Stringin: [String!]notIn: [String!]lt: Stringlte: Stringgt: Stringgte: Stringcontains: StringstartsWith: StringendsWith: Stringnot: NestedStringNullableFilter}
Mutations
createUser
type Mutation {createUser(data: UserCreateInput!): User}input UserCreateInput {name: String}type User {id: ID!name: String}
createUsers
type Mutation {createUsers(data: [UserCreateInput!]!): [User]}input UserCreateInput {name: String}type User {id: ID!name: String}
updateUser
type Mutation {updateUser(where: UserWhereUniqueInput!, data: UserUpdateInput!): User}input UserWhereUniqueInput {id: ID}input UserUpdateInput {name: String}type User {id: ID!name: String}
updateUsers
type Mutation {updateUsers(data: [UserUpdateArgs!]!): [User]}input UserUpdateArgs {where: UserWhereUniqueInput!data: UserUpdateInput!}input UserWhereUniqueInput {id: ID}input UserUpdateInput {name: String}type User {id: ID!name: String}
deleteUser
type Mutation {deleteUser(where: UserWhereUniqueInput!): User}input UserWhereUniqueInput {id: ID}type User {id: ID!name: String}
deleteUsers
type Mutation {deleteUsers(ids: [UserWhereUniqueInput!]!): [User]}input UserWhereUniqueInput {id: ID}type User {id: ID!name: String}
Errors
The Keystone GraphQL API is powered by Apollo Server.
When something goes wrong with a query or mutation, one or more errors will be returned in the errors
array returned to the GraphQL client.
Keystone provides custom errors where possible, including custom error codes and messages. These error codes and messages can be used to provide useful feedback to users, and also to help identify possible bugs in your system. The following error codes can be returned from the Keystone GraphQL API.
KS_USER_INPUT_ERROR
: The input to the operation is syntactically correct GraphQL, but the values provided are invalid. E.g, anorderBy
input without any keys.KS_ACCESS_DENIED
: The operation is not allowed because of an Access Control rule.KS_FILTER_DENIED
: The filter or ordering operation is not allowed because ofisFilterable
orisOrderable
rules.KS_VALIDATION_FAILURE
: The operation is not allowed because of a validation rule.KS_LIMITS_EXCEEDED
: The user has exceeded their query limits.KS_EXTENSION_ERROR
: An error was thrown while excuting a system extension function, such as a hook or an access control function.KS_ACCESS_RETURN_ERROR
: An invalid value was returned from an access control function.KS_RESOLVER_ERROR
: An error occured while resolving the input for a field.KS_RELATIONSHIP_ERROR
: An error occured while resolving the input relationship field.KS_PRISMA_ERROR
: An error occured while running a Prisma client operation.