Skip to main content
Glama
app.md8.17 kB
```typescript // NestJS Complete Application Template import { Controller, Get, Post, Put, Delete, Body, Param, Query, UseGuards, Injectable, Module, NestFactory, } from "@nestjs/common"; import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiQuery, ApiParam, } from "@nestjs/swagger"; import { IsString, IsEmail, IsOptional, IsEnum, MinLength, } from "class-validator"; import { JwtAuthGuard } from "./auth/jwt-auth.guard"; // ============================================ // DTOs (Data Transfer Objects) // ============================================ export class CreateUserDto { @IsEmail() email: string; @IsString() @MinLength(2) name: string; @IsString() @MinLength(8) password: string; } export class UpdateUserDto { @IsOptional() @IsString() name?: string; @IsOptional() @IsString() bio?: string; } export class CreatePostDto { @IsString() @MinLength(1) title: string; @IsString() content: string; @IsOptional() @IsEnum(["draft", "published"]) status?: "draft" | "published"; } export class QueryPostDto { @IsOptional() @IsString() search?: string; @IsOptional() @IsEnum(["draft", "published"]) status?: "draft" | "published"; @IsOptional() limit?: number = 20; @IsOptional() offset?: number = 0; } // ============================================ // Entities // ============================================ export interface User { id: string; email: string; name: string; bio?: string; createdAt: Date; updatedAt: Date; } export interface Post { id: string; title: string; content: string; authorId: string; status: "draft" | "published"; views: number; createdAt: Date; publishedAt?: Date; } // ============================================ // Services // ============================================ @Injectable() export class UsersService { private users: Map<string, User> = new Map(); private idCounter = 1; async findAll(): Promise<User[]> { return Array.from(this.users.values()); } async findById(id: string): Promise<User | undefined> { return this.users.get(id); } async findByEmail(email: string): Promise<User | undefined> { return Array.from(this.users.values()).find((u) => u.email === email); } async create(dto: CreateUserDto): Promise<User> { const id = String(this.idCounter++); const user: User = { id, email: dto.email, name: dto.name, createdAt: new Date(), updatedAt: new Date(), }; this.users.set(id, user); return user; } async update(id: string, dto: UpdateUserDto): Promise<User | undefined> { const user = this.users.get(id); if (!user) return undefined; const updated = { ...user, ...dto, updatedAt: new Date() }; this.users.set(id, updated); return updated; } async delete(id: string): Promise<boolean> { return this.users.delete(id); } } @Injectable() export class PostsService { private posts: Map<string, Post> = new Map(); private idCounter = 1; async findAll(query: QueryPostDto): Promise<{ data: Post[]; total: number }> { let posts = Array.from(this.posts.values()); if (query.status) { posts = posts.filter((p) => p.status === query.status); } if (query.search) { const search = query.search.toLowerCase(); posts = posts.filter( (p) => p.title.toLowerCase().includes(search) || p.content.toLowerCase().includes(search), ); } const total = posts.length; const data = posts.slice(query.offset, query.offset! + query.limit!); return { data, total }; } async findById(id: string): Promise<Post | undefined> { return this.posts.get(id); } async create(dto: CreatePostDto, authorId: string): Promise<Post> { const id = String(this.idCounter++); const post: Post = { id, title: dto.title, content: dto.content, authorId, status: dto.status || "draft", views: 0, createdAt: new Date(), }; this.posts.set(id, post); return post; } async publish(id: string): Promise<Post | undefined> { const post = this.posts.get(id); if (!post) return undefined; post.status = "published"; post.publishedAt = new Date(); return post; } async incrementViews(id: string): Promise<number> { const post = this.posts.get(id); if (!post) return 0; post.views++; return post.views; } async delete(id: string): Promise<boolean> { return this.posts.delete(id); } } // ============================================ // Controllers // ============================================ @ApiTags("users") @Controller("users") export class UsersController { constructor(private readonly usersService: UsersService) {} @Get() @ApiOperation({ summary: "Get all users" }) @ApiResponse({ status: 200, description: "List of users" }) async findAll(): Promise<User[]> { return this.usersService.findAll(); } @Get(":id") @ApiOperation({ summary: "Get user by ID" }) @ApiParam({ name: "id", description: "User ID" }) @ApiResponse({ status: 200, description: "User found" }) @ApiResponse({ status: 404, description: "User not found" }) async findOne(@Param("id") id: string): Promise<User | undefined> { return this.usersService.findById(id); } @Post() @ApiOperation({ summary: "Create a new user" }) @ApiResponse({ status: 201, description: "User created" }) async create(@Body() dto: CreateUserDto): Promise<User> { return this.usersService.create(dto); } @Put(":id") @UseGuards(JwtAuthGuard) @ApiBearerAuth() @ApiOperation({ summary: "Update user" }) async update( @Param("id") id: string, @Body() dto: UpdateUserDto, ): Promise<User | undefined> { return this.usersService.update(id, dto); } @Delete(":id") @UseGuards(JwtAuthGuard) @ApiBearerAuth() @ApiOperation({ summary: "Delete user" }) async delete(@Param("id") id: string): Promise<{ deleted: boolean }> { const deleted = await this.usersService.delete(id); return { deleted }; } } @ApiTags("posts") @Controller("posts") export class PostsController { constructor(private readonly postsService: PostsService) {} @Get() @ApiOperation({ summary: "Get all posts" }) @ApiQuery({ name: "search", required: false }) @ApiQuery({ name: "status", required: false, enum: ["draft", "published"] }) async findAll(@Query() query: QueryPostDto) { return this.postsService.findAll(query); } @Get(":id") @ApiOperation({ summary: "Get post by ID" }) async findOne(@Param("id") id: string) { const post = await this.postsService.findById(id); if (post) { await this.postsService.incrementViews(id); } return post; } @Post() @UseGuards(JwtAuthGuard) @ApiBearerAuth() @ApiOperation({ summary: "Create a new post" }) async create(@Body() dto: CreatePostDto) { // In real app, get authorId from request user return this.postsService.create(dto, "current-user-id"); } @Post(":id/publish") @UseGuards(JwtAuthGuard) @ApiBearerAuth() @ApiOperation({ summary: "Publish a post" }) async publish(@Param("id") id: string) { return this.postsService.publish(id); } @Delete(":id") @UseGuards(JwtAuthGuard) @ApiBearerAuth() async delete(@Param("id") id: string) { return { deleted: await this.postsService.delete(id) }; } } // ============================================ // Module // ============================================ @Module({ controllers: [UsersController, PostsController], providers: [UsersService, PostsService], exports: [UsersService, PostsService], }) export class AppModule {} // ============================================ // Bootstrap // ============================================ async function bootstrap() { const app = await NestFactory.create(AppModule); // Enable CORS app.enableCors(); // Global prefix app.setGlobalPrefix("api"); // Swagger setup would go here await app.listen(3000); console.log("Application running on http://localhost:3000"); } // bootstrap(); ```

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/millsydotdev/Code-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server