{"id":21577934,"url":"https://github.com/wesleysbmartins/node_api_swagger","last_synced_at":"2026-04-17T06:33:23.950Z","repository":{"id":255402929,"uuid":"848463152","full_name":"wesleysbmartins/node_api_swagger","owner":"wesleysbmartins","description":"Exemplo de API desenvolvida em NodeJS documentada com Swagger.","archived":false,"fork":false,"pushed_at":"2024-08-29T17:01:25.000Z","size":87,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-05T11:41:18.840Z","etag":null,"topics":["api","api-rest","backend","documentation","nodejs","server","store","swagger","swagger-ui","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wesleysbmartins.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-27T20:03:12.000Z","updated_at":"2024-08-29T17:04:19.000Z","dependencies_parsed_at":"2024-08-29T20:05:30.377Z","dependency_job_id":"233d38f1-58d7-4122-8910-28a15cee2250","html_url":"https://github.com/wesleysbmartins/node_api_swagger","commit_stats":null,"previous_names":["wesleysbmartins/node_api_swagger"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/wesleysbmartins/node_api_swagger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wesleysbmartins%2Fnode_api_swagger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wesleysbmartins%2Fnode_api_swagger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wesleysbmartins%2Fnode_api_swagger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wesleysbmartins%2Fnode_api_swagger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wesleysbmartins","download_url":"https://codeload.github.com/wesleysbmartins/node_api_swagger/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wesleysbmartins%2Fnode_api_swagger/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31918563,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T18:22:33.417Z","status":"online","status_checked_at":"2026-04-17T02:00:06.879Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","api-rest","backend","documentation","nodejs","server","store","swagger","swagger-ui","typescript"],"created_at":"2024-11-24T13:09:01.820Z","updated_at":"2026-04-17T06:33:23.927Z","avatar_url":"https://github.com/wesleysbmartins.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# API NodeJS Documentada com Swagger\nEsta é uma API desenvolvida em NodeJS como um exemplo para documentação com Swagger. Vamos abordar como criar a API, documenta-la e acessar sua documentação.\nComo esta é uma aplicação de exemplo eu criei um **\"Store\"** em memória apenas para utilizarmos como base de dados e fazer operações básicas de CRUD.\n\n### Inicie sua aplicação\nAbra o seu terminal na pasta desejada e inicie uma aplicação NodeJS:\n```shell\nnpm init -y\n```\n\nInstale as dependências necessárias para criar a API e documenta-la:\n```shell\nnpm install express cors helmet dotenv swagger-jsdoc swagger-ui-express\n```\nInstale as dependências de desenvolvimento:\n```shell\nnpm install -D @types/express @types/cors @types/node @types/swagger-jsdoc @types/swagger-ui-express nodemon ts-node typescript\n```\n\nConfigure os scripts do seu **package.json**:\n```json\n \"scripts\": {\n    \"build\": \"tsc\",\n    \"start\": \"node dist/server.js\",\n    \"dev\": \"nodemon src/server.ts\",\n    \"test\": \"echo \\\"Error: no test specified\\\" \u0026\u0026 exit 1\"\n  },\n```\n\n### Configuração Swagger\nNo meu caso eu criai uma classe para abstrair a configuração do arquivo main da aplicação:\n\n```ts\nexport class SwaggerConfig {\n    config: {\n        swaggerDefinition: {\n            openapi: string;\n            info : {\n                title: string;\n                version: string;\n                description: string;\n            };\n            servers: [{\n                url: string;\n                description: string;\n            }];\n        };\n        apis: string[];\n    }\n\n    constructor() {\n        const port = parseInt(`${process.env.PORT || 3000}`);\n\n        this.config = {\n            swaggerDefinition: {\n                // versao do swagger\n                openapi: \"3.0.0\",\n                info: {\n                    // node da aplicação\n                    title: \"API NodeJS/Swagger.\",\n                    // versão da documentação\n                    version: \"1.0.0\",\n                    // descrição da api\n                    description: \"API NodeJS documentada com Swagger.\"\n                },\n                // seus servidores\n                servers: [{\n                    // endereço do seu servidor back-end\n                    url: `http://localhost:${port}`,\n                    // descrição do seu servidor back-end\n                    description: \"Development Server.\"\n                }],\n            },\n            // caminho dos arquivos onde a documentação de cada endpoint será persistida\n            // no meu caso tenho documentação tanto nas minhas routes como nas controllers\n            apis: [\"./src/routes/**/*.ts\", './src/controllers/**/*.ts'],\n        };\n    }\n}\n```\n\n### Configuração Server\n```ts\nimport dotenv from \"dotenv\";\nimport express from \"express\";\nimport cors from \"cors\";\nimport helmet from \"helmet\";import swaggerJsdoc from \"swagger-jsdoc\";\nimport swaggerUi from \"swagger-ui-express\";\nimport { SwaggerConfig } from \"./infra/swagger/Swagger\";\nimport router from \"./routes\";\nimport { Store } from \"./infra/store/Store\";\n\ndotenv.config();\n\nconst app = express();\n\napp.use(cors());\n\napp.use(helmet());\n\napp.use(express.json())\n\napp.use(router);\n\nconst swagger = new SwaggerConfig();\n\nconst port = parseInt(`${process.env.PORT || 3000}`);\n\napp.use(\"/api-docs\", swaggerUi.serve, swaggerUi.setup(swaggerJsdoc(swagger.config)));\n\nconst UserStore = new Store()\n\napp.listen(port, () =\u003e console.log(`Server Running on PORT: ${port}.`));\n\nexport default UserStore;\n```\n\nAssim, você tem sua aplicação preparada para trabalhar com o Swagger, basta adicionar a documentação de seus endpoints, é recomendado que as deixe nas controllers para manter uma organização clara sobre cada endpoint.\n\n\u003cdetails\u003e\n    \u003csummary\u003eStore\u003c/summary\u003e\n\nO Store é uma classe que trabalha com dados genéricos, onde os objetos devem ter sempre um **id**.\nE temos operações  para inserir dados na store, atualizar, buscar e remover.\n```ts\nimport { IStore } from \"./IStore\";\n\nexport class StoreData {\n    id?: number;\n}\n\nexport class Store\u003cT extends StoreData\u003e implements IStore\u003cT\u003e {\n    private instance: T[];\n\n    constructor() {\n        this.instance = [];\n    }\n\n    get(): T[] {\n        return this.instance;\n    }\n\n    add(value: T): T[] {\n        value.id = this.instance.length + 1;\n\n        this.instance.push(value);\n        \n        return this.instance.sort();\n    }\n\n    update(value: T): T[] {\n        for(let i = 0; i \u003c this.instance.length; i++) {\n            if(this.instance[i].id === value.id) {\n                this.instance[i] = value;\n            }\n        }\n\n        return this.instance.sort();\n    }\n\n    remove(id: number): T[] {\n        this.instance = this.instance.filter((v) =\u003e v.id !== id);\n\n        return this.instance.sort();\n    }\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003eUsers\u003c/summary\u003e\n\nNessa api teremos operações onde será possível manipular dados de usuários.\n```ts\nimport { StoreData } from \"../infra/store/Store\";\n\nexport class User extends StoreData {\n    name: string;\n};\n```\n\u003c/details\u003e\n\n### Endpoints e suas Documentações\nNesta aplicação vamso ter endpoints para manipulação de dados de usuários, então teremos operações de criação, leitura, atualização e remoção, aqui veremos como documentar tais endpoints, passando seu endereço, descrição, método, parâmetros e respostas.\n\n\u003cdetails\u003e\n    \u003csummary\u003eCreate\u003c/summary\u003e\n\n```ts\n/**\n * @swagger\n * \n * /users/create:\n *   post:\n *     summary: Create User\n *     description: Criação de um usuário, no qual você deve enviar o `name` no body.\n *     requestBody:\n *       required: true\n *       content:\n *         application/json:\n *           schema:\n *             $ref: '#/components/schemas/User'\n *           example:\n *             name: \"Sherlock Holmes\"\n * \n *     responses:\n *       200:\n *         description: Success\n *         content:\n *           application/json:\n *             schema:\n *               type: array\n *               items:\n *                 $ref: '#/components/schemas/User'\n *             example:\n *               - id: 1\n *                 name: \"Sherlock Holmes\"\n *               - id: 2\n *                 name: \"John Watson\"\n *       500:\n *         description: Internal Server Error\n *         content:\n *           application/json:\n *             schema:\n *               type: object\n *               properties:\n *                 error:\n *                   type: string\n *                   description: Mensagem de erro\n *                   example: \"Name is required!\"\n */\nexport function CreateUser(req: Request, res: Response) {\n    try {\n        const user = req.body as User;\n\n        if(!user.name) {\n            throw new Error(\"Name is required!\");\n        }\n\n        res.status(200).send(UserStore.add(user));\n    } catch (err) {\n        const error = {\n            message: (err as Error).message,\n        };\n\n        res.status(500).send({ error });\n    }\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003eRead\u003c/summary\u003e\n\n```ts\n/**\n * @swagger\n * components:\n *   schemas:\n *     User:\n *       type: object\n *       properties:\n *         id:\n *           type: integer\n *           description: ID único do usuário\n *           example: 1\n *         name:\n *           type: string\n *           description: Nome do usuário\n *           example: \"Sherlock Holmes\"\n * \n * /users/getAll:\n *   get:\n *     summary: Get All Users\n *     description: Retorna um array de objetos `User`, cada um contendo o `id` e o `name`.\n *     responses:\n *       200:\n *         description: Success\n *         content:\n *           application/json:\n *             schema:\n *               type: array\n *               items:\n *                 $ref: '#/components/schemas/User'\n *             example:\n *               - id: 1\n *                 name: \"Sherlock Holmes\"\n *               - id: 2\n *                 name: \"John Watson\"\n */\nexport function GetAllUsers(req: Request, res: Response) {\n    try {\n        res.status(200).send(UserStore.get());\n    } catch (err) {\n        const error = {\n            message: (err as Error).message,\n        };\n\n        res.status(500).send({ error });\n    }\n}\n```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n    \u003csummary\u003eUpdate\u003c/summary\u003e\n\n```ts\n/**\n * @swagger\n * \n * /users/update:\n *   put:\n *     summary: Update User\n *     description: Atualização de um usuário, no qual você deve enviar o `name` que deseja atualizar e o `id` do usuário em questão no body.\n *     requestBody:\n *       required: true\n *       content:\n *         application/json:\n *           schema:\n *             $ref: '#/components/schemas/User'\n *           example:\n *             id: 1\n *             name: \"Sherlock Holmes\"\n * \n *     responses:\n *       200:\n *         description: Success\n *         content:\n *           application/json:\n *             schema:\n *               type: array\n *               items:\n *                 $ref: '#/components/schemas/User'\n *             example:\n *               - id: 1\n *                 name: \"Sherlock Holmes\"\n *               - id: 2\n *                 name: \"John Watson\"\n *       500:\n *         description: Internal Server Error\n *         content:\n *           application/json:\n *             schema:\n *               type: object\n *               properties:\n *                 error:\n *                   type: string\n *                   description: Mensagem de erro\n *                   example: \"Id and Name is required!\"\n */\nexport function UpdateUser(req: Request, res: Response) {\n    try {\n        const user = req.body as User;\n\n        if(!user.id || !user.name) {\n            throw new Error(\"Id and Name is required!\");\n        }\n\n        res.status(200).send(UserStore.update(user));\n    } catch (err) {\n        const error = {\n            message: (err as Error).message,\n        };\n\n        res.status(500).send({ error });\n    }\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003eDelete\u003c/summary\u003e\n\n```ts\n/**\n * @swagger\n * \n * /users/remove?:id:\n *   delete:\n *     summary: Remove User\n *     description: Remoção de um usuário, no qual você deve enviar o `id` do usuário em questão como parâmetro.\n *     parameters:\n *       - in: query\n *         name: id\n *         required: true\n *         schema:\n *           type: integer\n *         description: ID do usuário a ser removido\n *         example: 1\n * \n *     responses:\n *       200:\n *         description: Success\n *         content:\n *           application/json:\n *             schema:\n *               type: array\n *               items:\n *                 $ref: '#/components/schemas/User'\n *             example:\n *               - id: 1\n *                 name: \"Sherlock Holmes\"\n *               - id: 2\n *                 name: \"John Watson\"\n *       500:\n *         description: Internal Server Error\n *         content:\n *           application/json:\n *             schema:\n *               type: object\n *               properties:\n *                 error:\n *                   type: string\n *                   description: Mensagem de erro\n *                   example: \"Id is required!\"\n */\nexport function RemoveUser(req: Request, res: Response) {\n    try {\n        const { id } = req.query;\n\n        if(!id) {\n            throw new Error(\"Id is required!\");\n        }\n\n        res.status(200).send(UserStore.remove(parseInt(id as string)));\n    } catch (err) {\n        const error = {\n            message: (err as Error).message,\n        };\n\n        res.status(500).send({ error });\n    }\n}\n```\n\u003c/details\u003e\n\nPara acessar o Swagger da aplicação basta executa-lá e acessar o endpoint **http://localhost:3000/api-docs/**.\n\n![Swagger](./resources/image.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwesleysbmartins%2Fnode_api_swagger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwesleysbmartins%2Fnode_api_swagger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwesleysbmartins%2Fnode_api_swagger/lists"}