Thuta Learning
GraphQL
ProjectsWeb Developmentbeginner

Project 1 — Blog API with Apollo Server

What you'll walk away with

  • Explain the core ideas behind Project 1 — Blog API with Apollo Server
  • Run the sample GraphQL query or code and verify its output
  • Apply the technique correctly to the Tutorial Platform and production scenarios

Build the mental model

This project combines schema design, resolvers and context, and DataLoader batching from earlier lessons into one complete Blog API — `Post`/`Comment` types, a `posts` query, `createPost`/`addComment` mutations, and a DataLoader-backed `Post.comments` field. Layer the application as schema (contract), resolvers (glue), and repository/db (data access) for testability.

Connect it to a real scenario

Build the Tutorial Platform's blog section with this project — `Post` (id, title, body) and `Comment` (id, body, author) types, a `posts` query, `createPost`/`addComment` mutations, and a `commentsByPost` DataLoader batching comment reads. End-to-end test it by creating a post, adding two comments, then querying posts to confirm nested comments come back correctly.

Try the working example

typescript
const typeDefs = `#graphql
  type Post {
    id: ID!
    title: String!
    body: String!
    comments: [Comment!]!
  }

  type Comment {
    id: ID!
    body: String!
    author: String!
  }

  type Query {
    posts: [Post!]!
  }

  type Mutation {
    createPost(title: String!, body: String!): Post!
    addComment(postId: ID!, body: String!, author: String!): Comment!
  }
`;

const resolvers = {
  Query: {
    posts: (_p: unknown, _a: unknown, ctx: Context) => ctx.db.post.findMany(),
  },
  Mutation: {
    createPost: (_p: unknown, args: PostInput, ctx: Context) =>
      ctx.db.post.create({ data: args }),
    addComment: (_p: unknown, args: CommentInput, ctx: Context) =>
      ctx.db.comment.create({ data: args }),
  },
  Post: {
    comments: (post: Post, _a: unknown, ctx: Context) =>
      ctx.loaders.commentsByPost.load(post.id),
  },
};
You should see
You can run a working Blog API end to end with schema, resolvers, mutations, and DataLoader in place.

5-minute try-it

Add a `deletePost(id: ID!): Boolean!` mutation and write its resolver to also delete associated comments.

One important caution

Storing comments in one unrelated array and manually filtering by `postId` inside the `Post.comments` resolver grows into an O(N) cost as the project scales — use a database query or DataLoader instead.

Apollo Server — Getting StartedGraphQL

Easy traps

  • Storing comments in one unrelated array and manually filtering by `postId` inside the `Post.comments` resolver grows into an O(N) cost as the project scales — use a database query or DataLoader instead.
  • Validate sample queries and mutations on a local or test server with recoverable data before applying them to production.

Exercise

Add a `deletePost(id: ID!): Boolean!` mutation and write its resolver to also delete associated comments.

You'll know it worked when: You can run a working Blog API end to end with schema, resolvers, mutations, and DataLoader in place.

Project 1 — Blog API with Apollo Server | Thuta Learning