typescriptadvanced

GraphQL Server with Type Definitions

Build a GraphQL API server with type definitions, resolvers, and query/mutation support.

typescript
// Minimal GraphQL server using graphql-http pattern

// Type definitions (SDL)
const typeDefs = `
  type User {
    id: ID!
    name: String!
    email: String!
    posts: [Post!]!
  }

  type Post {
    id: ID!
    title: String!
    body: String!
    author: User!
    createdAt: String!
  }

  type Query {
    user(id: ID!): User
    users: [User!]!
    post(id: ID!): Post
  }

  type Mutation {
    createUser(name: String!, email: String!): User!
    createPost(title: String!, body: String!, authorId: ID!): Post!
  }
`;

// In-memory data
const users = new Map<string, { id: string; name: string; email: string }>();
const posts = new Map<string, { id: string; title: string; body: string; authorId: string; createdAt: string }>();

// Resolvers
const resolvers = {
  Query: {
    user: (_: unknown, { id }: { id: string }) => users.get(id) ?? null,
    users: () => [...users.values()],
    post: (_: unknown, { id }: { id: string }) => posts.get(id) ?? null,
  },
  Mutation: {
    createUser: (_: unknown, args: { name: string; email: string }) => {
      const user = { id: crypto.randomUUID(), ...args };
      users.set(user.id, user);
      return user;
    },
    createPost: (_: unknown, args: { title: string; body: string; authorId: string }) => {
      if (!users.has(args.authorId)) throw new Error('Author not found');
      const post = {
        id: crypto.randomUUID(),
        title: args.title,
        body: args.body,
        authorId: args.authorId,
        createdAt: new Date().toISOString(),
      };
      posts.set(post.id, post);
      return post;
    },
  },
  User: {
    posts: (user: { id: string }) =>
      [...posts.values()].filter(p => p.authorId === user.id),
  },
  Post: {
    author: (post: { authorId: string }) => users.get(post.authorId),
  },
};

// HTTP handler (framework-agnostic)
import http from 'http';

http.createServer(async (req, res) => {
  if (req.method === 'POST' && req.url === '/graphql') {
    let body = '';
    for await (const chunk of req) body += chunk;
    const { query, variables } = JSON.parse(body);
    // In production, use graphql-js executeSync or graphql-http
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ data: 'Use graphql-js execute()' }));
  } else {
    res.writeHead(404);
    res.end();
  }
}).listen(4000, () => console.log('GraphQL at http://localhost:4000/graphql'));

export { typeDefs, resolvers };

Sponsored

Railway

Use Cases

  • GraphQL API development
  • Type-safe API definitions
  • Relational data querying

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.