esquema inicial
Cuando se empieza a crear una API de Graphql es comun con iniciar con una estructura como esta.
(generado con tree: tree . -I node_modules)
.
├── package.json
├── package-lock.json
└── src
├── index.js
├── resolvers.js
└── schema.js
1 directory, 5 files
schema.js
import { gql } from "apollo-server";
export const typeDefs = gql`
type Query {
author(id: Int!): Author
book(id: Int!): Book
}
type Author {
id: Int!
firstName: String
lastName: String
books: [Book]
}
type Book {
title: String
author: Author
}
`;
export const resolvers = {
Query: {
author() {},
book() {},
},
};
index.js
import { ApolloServer } from "apollo-server";
import { typeDefs, resolvers } from "./schema.js";
async function startApolloServer() {
const server = new ApolloServer({ typeDefs, resolvers });
const { url } = await server.listen();
console.log(`🚀 Server ready at ${url}`);
}
startApolloServer();
Dividir Schema en multiples archivos
en lugar de tener todo nuestra definicion de esquema (schema definition) en un solo archivo es mucho más preferible para mantenimiento del código tenerlo en multiples archivos.
De hecho el DSL que usan los esquemas de graphql al final son solo Strings, asi que podemos dividirlo en multiples string y al final contactenarlos todos.
author.js
import { gql } from "apollo-server";
export const typeDefs = gql`
type Author {
id: Int!
firstName: String
lastName: String
books: [Book]
}
`;
book.js
import { gql } from "apollo-server";
export const typeDefs = gql`
type Book {
title: String
author: Author
}
`;
actualicemos schema.js
import { gql } from "apollo-server";
import { typeDefs as Author } from "./author.js";
import { typeDefs as Book } from "./book.js";
export const RootTypeDefs = gql`
type Query {
author(id: Int!): Author
book(id: Int!): Book
}
`;
export const typeDefs = [RootTypeDefs, Author, Book];
en schema.js he renombrado typeDefs a RootTypeDefs para especificar que esta la raiz de todas las consultas. y luego he exportado un arreglo llamado typeDefs que contiene todas las querys. Es decir estoy exportando un arreglo de Strings. que apollo server soporta puede recibir como argumento.
resolvers
book.js import { gql } from "apollo-server";
export const typeDefs = gql type Book { title: String author: Author };
export const resolvers = { Book: { author: () => { }, } };
author.js
import { gql } from "apollo-server";
export const typeDefs = gql type Author { id: Int! firstName: String lastName: String books: [Book] };
export const resolvers = { Author: { books: () => { }, } };
schema.js
// TypeDefs
...
// resolvers
import { resolvers as BookResolvers } from "./book.js";
import { resolvers as AuthorResolver } from "./author.js";
export const RootTypeDefs = gql`
...
`;
const rootResolver = {
Query: {
author() {},
book() {},
},
};
export const typeDefs = [RootTypeDefs, Author, Book];
export const resolvers = [rootResolver, BookResolvers, AuthorResolver];
Extender schema
Aun estamos definiendo authors y books en nuestro nivel más alto de esquema, pero debido estos deberian estar en sus respectivos archivos book.js y author.js
export const RootTypeDefs = gql`
type Query {
_empty: String
}
extend type Query {
author(id: Int!): Author
}
extend type Query {
book(id: Int!): Book
}
`;
// author.js
export const typeDef = ` extend type Query { author(id: Int!): Author }
type Author { id: Int! firstName: String lastName: String books: [Book] } `;
book.js
import { gql } from "apollo-server";
export const typeDefs = gql` extend type Query { book(id: Int!): Book }
type Book { title: String author: Author } `;
export const resolvers = { Book: { author: () => {}, }, };
schema.js
export const RootTypeDefs = gql type Query { _empty: String };
Recomendaciones finales
- When learning, prototyping or even building a POC, putting your whole schema in a single file is likely fine: There are benefits to be able to go through your whole schema really quickly, or explain it to a coworker
- You can organize your schema and resolvers by feature: for example, putting the stuff related to the checkout system together might make sense in an ecommerce site.
- Keep your resolvers in the same file as the schema definition for the fields they implement. This will allow you to reason about your code efficiently.
- Wrap your SDL type definitions with a gql tag using graphql-tag. If you’re using a GraphQL plugin for your editor or formatting your code with Prettier, you’ll be able to get syntax highlighting for SDL within your code editor as long as you prefix it with the gql tag
