Nexus Documentation
repository·main·Indexed 25 days ago
https://github.com/graphql-nexus/nexusNexus is a declarative, code-first, and strongly typed GraphQL schema construction library for TypeScript and JavaScript. It enables developers to build scalable schemas with full type-safety and integrates with tools like Apollo Server and graphql-js. The library uses a reflection system via makeSchema to generate GraphQL SDL and TypeScript type definitions.
What's inside Nexus
- Nexus provides specialized tools to implement GraphQL Union types and Interface types safely and easily. This guide covers how to leverage these abstract types to model complex data structures in your schema.
Understand Nullability Defaults in Nexus
mainBy default, Nexus treats both inputs (arguments and input object fields) and outputs (object type fields) as nullable.
Implications of default nullability:
- Outputs: Being nullable allows you to change output requirements later without breaking clients, but requires client developers to handle
nullcases. - Inputs: Being nullable makes the API easier for clients to consume (no upfront configuration required), but requires more careful design as making an input required later is a breaking change.
- TypeScript Types: When an input is nullable, the TypeScript type in your resolver will be
null | undefined.nullrepresents an explicitnullpassed by the client, whileundefinedrepresents the client omitting the input entirely.
- Outputs: Being nullable allows you to change output requirements later without breaking clients, but requires client developers to handle
Understand the Nexus API design principles
mainThe Nexus API is designed around four core principles to ensure a high-quality developer experience. When extending the API or suggesting changes, ensure they align with these goals:
- Type-Safety: TypeScript type generation is provided by default.
- Readability: The API structure should be easy to read and understand.
- Developer ergonomics: The API should be intuitive and easy to use.
- Prettier compatibility: The API is designed to work seamlessly with Prettier formatting.
Compare Schema-First vs. Code-First approaches
mainNexus uses a code-first approach, which differs from the traditional schema-first approach.
In a schema-first approach, you define a schema using GraphQL Schema Definition Language (SDL) and then write separate resolver logic to provide data. This often leads to context switching between SDL and JavaScript/TypeScript and requires keeping schema and resolvers in sync.
In the code-first approach used by Nexus, you write both the schema and the resolver logic in the same place using a single language (JavaScript or TypeScript). This ensures schema and resolver co-location and reduces the need for manual synchronization.
Understand Source Types in Nexus
mainIn Nexus (and GraphQL generally), there is a distinction between the API Types seen by the client and the Source Types used internally by resolvers.
When a field resolver returns an object, that object is the Source Type. This data is then passed as the first argument (
source) to all subsequent field resolvers for that object type. This allows you to map raw database records (like a row from a SQL table) to a structured GraphQL schema.For example, a
Query.userresolver might fetch a database record containing{ firstname: 'Foo', lastname: 'Bar' }. TheUserobject type then uses this record as itssourceto resolve fields likefullName.Understand Nexus TypeScript type generation concepts
mainNexus generates types that combine your schema, field configurations, and the GraphQL resolution algorithm to provide type safety with minimal manual annotation. Key concepts include:
- Root Types: The type representation of the value used to resolve fields (the first argument passed to
resolve). This can be a plain JS object, a database model, a Mongoose document, or a JS class. For Relay-style paginationEdgetypes where no explicit backing type exists, Nexus generates an assumed type which can be overridden with a concrete type. - Field Type: The valid return value for a field. Because GraphQL allows promises at any level, Nexus wraps these in a
MaybePromiseDeep<T>type to represent potential asynchronous values.
- Root Types: The type representation of the value used to resolve fields (the first argument passed to
Explore GraphQL Nexus examples by language
mainThe repository provides several examples categorized by language and complexity:
Featured TypeScript Example
- ghost-graphql: Demonstrates the use of
schematsand inferred types.
JavaScript Examples
- githunt-api
TypeScript Examples
- ts-ast-reader
- apollo-fullstack
- star-wars
- kitchen-sink
- with-prisma (Note: This example requires manual setup via its own README and is not included in the bulk
examplescommand).
- ghost-graphql: Demonstrates the use of
Migrate `t.crud` Query fields to plain Nexus
mainTo migrate a query like
t.crud.posts()ort.crud.post(), define the field explicitly usingt.fieldort.nonNull.list.nonNull.fieldand define any requiredinputObjectTypefor arguments (e.g.,PostWhereUniqueInput). Use the SDL Converter to assist in generating the necessary Nexus code from your existing GraphQL schema.// Migrating t.crud.posts() const Query = objectType({ name: "Query", definition(t) { t.nonNull.list.nonNull.field("posts", { type: Post, args: { after: arg({ type: PostWhereUniqueInput }), before: arg({ type: PostWhereUniqueInput }), first: intArg(), last: intArg(), }, }) } }) const PostWhereUniqueInput = inputObjectType({ name: "PostWhereUniqueInput", definition(t) { t.int("id") } });Set up Development Mode with ts-node-dev and type checking
mainTo replicate the development experience of the Nexus Framework, use two separate processes: one for running the API (without type checking to avoid blocking the reflection system) and one for background type checking.
Add the following to your
package.jsonscripts:{ "scripts": { "dev": "ts-node-dev --transpile-only ./your/main/module", "dev:typecheck": "tsc --noEmit --watch" } }dev: Usests-node-devto run your API. The--transpile-onlyflag is critical so that type errors do not halt the process, allowing the Nexus reflection system to generate schema types.dev:typecheck: Usestscin watch mode to provide static type checking in a separate terminal.
Include scalars in schema generation
mainWhen using custom scalars, you must include the scalar in the
typesarray of themakeSchemaconfiguration to ensure it is part of the generated schema.const schema = makeSchema({ types: [GQLDate] // Add Scalar to Array })Configure Nexus build scripts for Next.js
mainTo ensure full type safety during the Next.js build process, you must run the Nexus type generation before
next build. Add a dedicated typegen script to yourpackage.jsonand update yourbuildcommand to chain them together.{ "scripts": { "dev": "next dev", "build:nexus-typegen": "ts-node --compiler-options '{\"module\":\"CommonJS\"}' --transpile-only schema", "build": "npm run build:nexus-typegen && next build", "start": "next start" } }Configure TypeScript for Nexus
mainCreate a
tsconfig.jsonfile in your project root to enable full TypeScript support for your Nexus project.{ "compilerOptions": { "target": "ES2018", "module": "commonjs", "lib": ["esnext"], "strict": true, "rootDir": ".", "outDir": "dist", "sourceMap": true, "esModuleInterop": true } }