Introducción a GraphQL API con TypeScript
GraphQL es un lenguaje de consultas para tu API que permite a los clientes solicitar solo los datos que realmente necesitan. En combinación con TypeScript, obtienes tipado estricto, autocompletado en el IDE y menos errores en tiempo de compilación. En este tutorial crearemos una API GraphQL completa desde cero, usando TypeScript y Apollo Server.
Esta guía es adecuada para desarrolladores familiarizados con los fundamentos de JavaScript y Node.js. Recorreremos el camino desde la instalación de dependencias hasta la prueba de la API terminada.
1. Configuración del proyecto e instalación de dependencias
Primero crearemos un nuevo proyecto e instalaremos los paquetes necesarios. Abre la terminal y ejecuta:
mkdir graphql-ts-tutorialcd graphql-ts-tutorialnpm init -yInstala TypeScript, Apollo Server y GraphQL:
npm install apollo-server graphqlnpm install -D typescript @types/node ts-node nodemonCrea el archivo tsconfig.json para la configuración de TypeScript:
{ "compilerOptions": { "target": "ES2020", "module": "commonjs", "rootDir": "./src", "outDir": "./dist", "strict": true, "esModuleInterop": true, "skipLibCheck": true }, "include": ["src/**/*"]}Crea la carpeta src y el archivo src/index.ts — este será el punto de entrada de nuestra aplicación.
2. Creación del esquema GraphQL y tipos TypeScript
En GraphQL, el esquema define los tipos de datos y las operaciones disponibles para el cliente. Crearemos un esquema simple para gestionar libros.
Archivo src/schema.ts:
import { gql } from 'apollo-server';
export const typeDefs = gql` type Book { id: ID! title: String! author: String! publishedYear: Int }
type Query { books: [Book] book(id: ID!): Book }
type Mutation { addBook(title: String!, author: String!, publishedYear: Int): Book deleteBook(id: ID!): Book }`;Ahora definamos las interfaces de TypeScript para nuestros datos. Crea src/types.ts:
export interface Book { id: string; title: string; author: string; publishedYear?: number;}Ten en cuenta: las interfaces de TypeScript son necesarias para la lógica interna, mientras que los tipos de GraphQL son para la interacción cliente-servidor. Deben estar coordinados.
3. Implementación de resolvers y servidor
Los resolvers son funciones que devuelven datos para cada campo del esquema. Crearemos el archivo src/resolvers.ts con una simulación de base de datos:
import { Book } from './types';
let books: Book[] = [ { id: '1', title: 'Guerra y paz', author: 'León Tolstói', publishedYear: 1869 }, { id: '2', title: 'Crimen y castigo', author: 'Fiódor Dostoyevski', publishedYear: 1866 },];
export const resolvers = { Query: { books: (): Book[] => books, book: (_: any, args: { id: string }): Book | undefined => { return books.find(book => book.id === args.id); }, }, Mutation: { addBook: (_: any, args: { title: string; author: string; publishedYear?: number }): Book => { const newBook: Book = { id: String(books.length + 1), title: args.title, author: args.author, publishedYear: args.publishedYear, }; books.push(newBook); return newBook; }, deleteBook: (_: any, args: { id: string }): Book | null => { const index = books.findIndex(book => book.id === args.id); if (index === -1) return null; const deletedBook = books.splice(index, 1)[0]; return deletedBook; }, },};Ahora conectemos todo en el archivo principal src/index.ts:
import { ApolloServer } from 'apollo-server';import { typeDefs } from './schema';import { r