From 812c2d86d41d8ee716ade29a7fd04e42db5554bc Mon Sep 17 00:00:00 2001 From: Jachin Date: Tue, 23 Sep 2025 18:31:16 +0800 Subject: [PATCH] feat(server): add Swagger API docs (#13455) ## Summary by CodeRabbit * **New Features** * Interactive API documentation available at /api/docs when running in development. * **Chores** * Added a development dependency to enable generation of the API documentation. --------- Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com> Co-authored-by: DarkSky --- packages/backend/server/package.json | 1 + packages/backend/server/src/server.ts | 15 ++++++ yarn.lock | 74 +++++++++++++++++++++++---- 3 files changed, 79 insertions(+), 11 deletions(-) diff --git a/packages/backend/server/package.json b/packages/backend/server/package.json index fe834c5cb2..44f98ffabb 100644 --- a/packages/backend/server/package.json +++ b/packages/backend/server/package.json @@ -128,6 +128,7 @@ "@affine-tools/utils": "workspace:*", "@affine/graphql": "workspace:*", "@faker-js/faker": "^10.0.0", + "@nestjs/swagger": "^11.2.0", "@nestjs/testing": "patch:@nestjs/testing@npm%3A10.4.15#~/.yarn/patches/@nestjs-testing-npm-10.4.15-d591a1705a.patch", "@types/cookie-parser": "^1.4.8", "@types/express": "^5.0.1", diff --git a/packages/backend/server/src/server.ts b/packages/backend/server/src/server.ts index 69eb93dd1f..a130dd9f81 100644 --- a/packages/backend/server/src/server.ts +++ b/packages/backend/server/src/server.ts @@ -59,6 +59,21 @@ export async function run() { const adapter = new SocketIoAdapter(app); app.useWebSocketAdapter(adapter); + if (env.dev) { + const { SwaggerModule, DocumentBuilder } = await import('@nestjs/swagger'); + // Swagger API Docs + const docConfig = new DocumentBuilder() + .setTitle('AFFiNE API') + .setDescription(`AFFiNE Server ${env.version} API documentation`) + .setVersion(`${env.version}`) + .build(); + const documentFactory = () => SwaggerModule.createDocument(app, docConfig); + SwaggerModule.setup('/api/docs', app, documentFactory, { + useGlobalPrefix: true, + swaggerOptions: { persistAuthorization: true }, + }); + } + const url = app.get(URLHelper); const listeningHost = '0.0.0.0'; diff --git a/yarn.lock b/yarn.lock index 137b58ae79..393e9ea5b7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -945,6 +945,7 @@ __metadata: "@nestjs/platform-express": "npm:^11.0.12" "@nestjs/platform-socket.io": "npm:^11.0.12" "@nestjs/schedule": "npm:^6.0.0" + "@nestjs/swagger": "npm:^11.2.0" "@nestjs/testing": "patch:@nestjs/testing@npm%3A10.4.15#~/.yarn/patches/@nestjs-testing-npm-10.4.15-d591a1705a.patch" "@nestjs/throttler": "npm:^6.4.0" "@nestjs/websockets": "npm:^11.0.12" @@ -7963,6 +7964,13 @@ __metadata: languageName: node linkType: hard +"@microsoft/tsdoc@npm:0.15.1": + version: 0.15.1 + resolution: "@microsoft/tsdoc@npm:0.15.1" + checksum: 10/1a92612883088fe184dba596e7ba7a0daef0e6981caeca22bad6ad551d2247294f12e368537d0d8192525cf5743f7f15fcc2ad7b3b849f26a09a15ffdd89fd0c + languageName: node + linkType: hard + "@modelcontextprotocol/sdk@npm:^1.16.0, @modelcontextprotocol/sdk@npm:^1.8.0": version: 1.16.0 resolution: "@modelcontextprotocol/sdk@npm:1.16.0" @@ -9285,6 +9293,34 @@ __metadata: languageName: node linkType: hard +"@nestjs/swagger@npm:^11.2.0": + version: 11.2.0 + resolution: "@nestjs/swagger@npm:11.2.0" + dependencies: + "@microsoft/tsdoc": "npm:0.15.1" + "@nestjs/mapped-types": "npm:2.1.0" + js-yaml: "npm:4.1.0" + lodash: "npm:4.17.21" + path-to-regexp: "npm:8.2.0" + swagger-ui-dist: "npm:5.21.0" + peerDependencies: + "@fastify/static": ^8.0.0 + "@nestjs/common": ^11.0.1 + "@nestjs/core": ^11.0.1 + class-transformer: "*" + class-validator: "*" + reflect-metadata: ^0.1.12 || ^0.2.0 + peerDependenciesMeta: + "@fastify/static": + optional: true + class-transformer: + optional: true + class-validator: + optional: true + checksum: 10/2f8cee1f58ea5d887939d0d6f230f272a2526900057515d95253fb6d6c96dcd2d110396d70e9b74e6342cf83f4575b4dbe58ae97ba6252270b8318dcaa5fc8cd + languageName: node + linkType: hard + "@nestjs/testing@npm:10.4.15": version: 10.4.15 resolution: "@nestjs/testing@npm:10.4.15" @@ -12711,6 +12747,13 @@ __metadata: languageName: node linkType: hard +"@scarf/scarf@npm:=1.4.0": + version: 1.4.0 + resolution: "@scarf/scarf@npm:1.4.0" + checksum: 10/1b39a18fa29e91cfbc134c588e20c5f01a1b21ec4473614123801155b48378e9c3bf72adaca8c67e433ae951ab653268e9502cc5733230d8927532f74a6b89c9 + languageName: node + linkType: hard + "@sec-ant/readable-stream@npm:^0.4.1": version: 0.4.1 resolution: "@sec-ant/readable-stream@npm:0.4.1" @@ -24904,6 +24947,17 @@ __metadata: languageName: node linkType: hard +"js-yaml@npm:4.1.0, js-yaml@npm:^4.0.0, js-yaml@npm:^4.1.0": + version: 4.1.0 + resolution: "js-yaml@npm:4.1.0" + dependencies: + argparse: "npm:^2.0.1" + bin: + js-yaml: bin/js-yaml.js + checksum: 10/c138a34a3fd0d08ebaf71273ad4465569a483b8a639e0b118ff65698d257c2791d3199e3f303631f2cb98213fa7b5f5d6a4621fd0fff819421b990d30d967140 + languageName: node + linkType: hard + "js-yaml@npm:^3.13.1, js-yaml@npm:^3.14.1": version: 3.14.1 resolution: "js-yaml@npm:3.14.1" @@ -24916,17 +24970,6 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:^4.0.0, js-yaml@npm:^4.1.0": - version: 4.1.0 - resolution: "js-yaml@npm:4.1.0" - dependencies: - argparse: "npm:^2.0.1" - bin: - js-yaml: bin/js-yaml.js - checksum: 10/c138a34a3fd0d08ebaf71273ad4465569a483b8a639e0b118ff65698d257c2791d3199e3f303631f2cb98213fa7b5f5d6a4621fd0fff819421b990d30d967140 - languageName: node - linkType: hard - "jsbn@npm:1.1.0": version: 1.1.0 resolution: "jsbn@npm:1.1.0" @@ -33132,6 +33175,15 @@ __metadata: languageName: node linkType: hard +"swagger-ui-dist@npm:5.21.0": + version: 5.21.0 + resolution: "swagger-ui-dist@npm:5.21.0" + dependencies: + "@scarf/scarf": "npm:=1.4.0" + checksum: 10/5e34f4337b06d64ee6bbd64940cc63ace7c457deb98a1de2a387833c6d919543bfed1da662827191fd6c6c6762cc2f52b7ca3f316932a9bc3b12d51b718c5424 + languageName: node + linkType: hard + "swap-case@npm:^2.0.2": version: 2.0.2 resolution: "swap-case@npm:2.0.2"