How do you create a full CRUD GraphQL API for posts in Nest JS?
Published: 2024-06-09 10:10:32

Sure! I'll guide you through creating a GraphQL API endpoint for posts in an existing NestJS project. Here are the steps you need to follow:

1. **Install necessary dependencies:**

   First, ensure you have the necessary GraphQL dependencies installed in your NestJS project. Run the following command in your project directory:

   ```bash
   npm install @nestjs/graphql graphql-tools graphql apollo-server-express
   ```

2. **Set up GraphQL module:**

   In your `app.module.ts`, import and configure the GraphQL module:

   ```typescript
   import { Module } from '@nestjs/common';
   import { GraphQLModule } from '@nestjs/graphql';
   import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
   import { join } from 'path';
   import { PostsModule } from './posts/posts.module'; // Ensure this path is correct

   @Module({
     imports: [
       GraphQLModule.forRoot<ApolloDriverConfig>({
         driver: ApolloDriver,
         autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
       }),
       PostsModule,
     ],
   })
   export class AppModule {}
   ```

3. **Create the Posts module, service, and resolver:**

   Generate the posts module, service, and resolver using the Nest CLI:

   ```bash
   nest generate module posts
   nest generate service posts
   nest generate resolver posts
   ```

4. **Define the Post entity:**

   Create a `post.entity.ts` file inside the `posts` directory with the following content:

   ```typescript
   export class Post {
     id: number;
     title: string;
     content: string;
   }
   ```

5. **Create Post DTOs:**

   Create `create-post.input.ts` and `update-post.input.ts` inside the `posts` directory:

   ```typescript
   // create-post.input.ts
   import { InputType, Field } from '@nestjs/graphql';

   @InputType()
   export class CreatePostInput {
     @Field()
     title: string;

     @Field()
     content: string;
   }
   ```

   ```typescript
   // update-post.input.ts
   import { InputType, Field, Int, PartialType } from '@nestjs/graphql';

   @InputType()
   export class UpdatePostInput extends PartialType(CreatePostInput) {
     @Field(() => Int)
     id: number;
   }
   ```

6. **Update the Post service:**

   Implement the necessary methods in `posts.service.ts`:

   ```typescript
   import { Injectable } from '@nestjs/common';
   import { CreatePostInput } from './dto/create-post.input';
   import { UpdatePostInput } from './dto/update-post.input';
   import { Post } from './entities/post.entity';

   @Injectable()
   export class PostsService {
     private posts: Post[] = [];
     private idCounter = 1;

     create(createPostInput: CreatePostInput): Post {
       const newPost = { id: this.idCounter++, ...createPostInput };
       this.posts.push(newPost);
       return newPost;
     }

     findAll(): Post[] {
       return this.posts;
     }

     findOne(id: number): Post {
       return this.posts.find(post => post.id === id);
     }

     update(id: number, updatePostInput: UpdatePostInput): Post {
       const postIndex = this.posts.findIndex(post => post.id === id);
       if (postIndex === -1) return null;
       this.posts[postIndex] = { ...this.posts[postIndex], ...updatePostInput };
       return this.posts[postIndex];
     }

     remove(id: number): Post {
       const postIndex = this.posts.findIndex(post => post.id === id);
       if (postIndex === -1) return null;
       const removedPost = this.posts.splice(postIndex, 1);
       return removedPost[0];
     }
   }
   ```

7. **Define the Post resolver:**

   Implement the resolver in `posts.resolver.ts`:

   ```typescript
   import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql';
   import { PostsService } from './posts.service';
   import { Post } from './entities/post.entity';
   import { CreatePostInput } from './dto/create-post.input';
   import { UpdatePostInput } from './dto/update-post.input';

   @Resolver(of => Post)
   export class PostsResolver {
     constructor(private readonly postsService: PostsService) {}

     @Mutation(() => Post)
     createPost(@Args('createPostInput') createPostInput: CreatePostInput) {
       return this.postsService.create(createPostInput);
     }

     @Query(() => [Post], { name: 'posts' })
     findAll() {
       return this.postsService.findAll();
     }

     @Query(() => Post, { name: 'post' })
     findOne(@Args('id', { type: () => Int }) id: number) {
       return this.postsService.findOne(id);
     }

     @Mutation(() => Post)
     updatePost(@Args('updatePostInput') updatePostInput: UpdatePostInput) {
       return this.postsService.update(updatePostInput.id, updatePostInput);
     }

     @Mutation(() => Post)
     removePost(@Args('id', { type: () => Int }) id: number) {
       return this.postsService.remove(id);
     }
   }
   ```

8. **Update the Posts module:**

   Ensure the `posts.module.ts` includes the service and resolver:

   ```typescript
   import { Module } from '@nestjs/common';
   import { PostsService } from './posts.service';
   import { PostsResolver } from './posts.resolver';

   @Module({
     providers: [PostsService, PostsResolver],
   })
   export class PostsModule {}
   ```

9. **Define the GraphQL schema:**

   Ensure your `post.entity.ts` is decorated with GraphQL decorators:

   ```typescript
   import { ObjectType, Field, Int } from '@nestjs/graphql';

   @ObjectType()
   export class Post {
     @Field(() => Int)
     id: number;

     @Field()
     title: string;

     @Field()
     content: string;
   }
   ```

Now, you should have a fully functional GraphQL API for managing posts in your NestJS project. You can start your server and access the GraphQL playground at `http://localhost:3000/graphql` to test your queries and mutations.

Disclaimer: This content is generated by AI.