UNPKG

@wearesage/schema

Version:

A flexible schema definition and validation system for TypeScript with multi-database support

136 lines (98 loc) 3.38 kB
# GraphQL API Integration Example This example demonstrates how to integrate the SAGE schema system with GraphQL, automatically generating a complete API from your entity definitions. ## Overview The example shows how to: 1. Generate a GraphQL schema from your entity metadata 2. Create GraphQL resolvers backed by your entity repositories 3. Support multiple database types through a unified GraphQL API ## Prerequisites - Node.js v14+ and npm/yarn - MongoDB, Neo4j, and PostgreSQL for the underlying datastores ## Running the Example ```bash # From the project root npm install npm run build node dist/examples/graphql/index.js ``` This will output the generated GraphQL schema and resolver structure. ## How It Works ### Schema Generation The example automatically generates a GraphQL schema from your entity metadata, including: - Types for each entity with fields matching your properties - Query resolvers for fetching entities - Mutation resolvers for creating, updating, and deleting entities - Input types for mutations - Proper handling of relationships ### Resolvers The generated resolvers use your repositories to: - Fetch entities from the appropriate database - Create and update entities with proper validation - Handle relationships across different databases ### Multi-Database Support The example supports entities stored in different databases: - Users in MongoDB - Posts in Neo4j - Tags in PostgreSQL All accessible through a single GraphQL API! ## Extending for Production To use this in a production environment, you would: 1. **Set up a GraphQL server** (e.g., Apollo Server): ```typescript import { ApolloServer } from 'apollo-server'; import { generateGraphQLTypes, generateResolvers } from './graphql-generator'; const typeDefs = generateGraphQLTypes(registry); const resolvers = generateResolvers(registry, repositories); const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => ({ // Add authentication, etc. }) }); server.listen().then(({ url }) => { console.log(`🚀 Server ready at ${url}`); }); ``` 2. **Add authentication and authorization**: ```typescript // In your context builder const context = ({ req }) => { const token = req.headers.authorization || ''; const user = verifyToken(token); return { user }; }; // In your resolvers const resolvers = { Query: { post: (_, { id }, { user }) => { if (!user) throw new Error('Not authenticated'); return postRepo.findById(id); } } }; ``` 3. **Add data loaders for performance**: ```typescript import DataLoader from 'dataloader'; const context = () => { return { loaders: { user: new DataLoader(ids => userRepo.findByIds(ids)), post: new DataLoader(ids => postRepo.findByIds(ids)), tag: new DataLoader(ids => tagRepo.findByIds(ids)) } }; }; // In your resolvers Post: { author: (post, _, { loaders }) => { return loaders.user.load(post.authorId); } } ``` ## Benefits of This Approach - **Zero-Boilerplate API**: Your GraphQL API is automatically generated from your entity definitions - **Type Safety**: Full TypeScript support ensures type safety across your entire stack - **Database Flexibility**: Use the right database for each entity type - **Unified API**: Clients access a single, coherent API regardless of the underlying database structure