├── README.md ├── src ├── users.js └── endpoints.js ├── package.json ├── index.js ├── .gitignore ├── LICENSE ├── swagger.js └── swagger-output.json /README.md: -------------------------------------------------------------------------------- 1 | # example-swagger-autogen 2 | 3 | Install the dependencies: 4 | 5 | ```bash 6 | $ npm install 7 | ``` 8 | 9 | Use the command below to generate the documentation at project startup: 10 | 11 | ```bash 12 | $ npm run start-gendoc 13 | ``` 14 | 15 | Use the command below to start the project without generating the documentation: 16 | 17 | ```bash 18 | $ npm start 19 | ``` 20 | 21 | Run the project and access the documentation at: 22 | 23 | [http://localhost:3000/doc](http://localhost:3000/doc) 24 | 25 | ## Screenshots 26 | See the result after construction: 27 | 28 | ![](https://raw.githubusercontent.com/davibaltar/public-store/master/screen-swagger-autogen.png) 29 | 30 | 31 | ## License 32 | [MIT](LICENSE) License -------------------------------------------------------------------------------- /src/users.js: -------------------------------------------------------------------------------- 1 | 2 | function addUser(param) { 3 | return true 4 | } 5 | 6 | function getUser(param) { 7 | const user = { 8 | name: "Lewis Doe", 9 | age: 32, 10 | parents: { 11 | father: "Simon Doe", 12 | mother: "Marie Doe" 13 | }, 14 | diplomas: [ 15 | { 16 | school: "ABC University", 17 | year: 2020, 18 | completed: true, 19 | internship: { 20 | hours: 310, 21 | location: "ABC Company" 22 | } 23 | } 24 | ] 25 | } 26 | return user 27 | } 28 | 29 | 30 | module.exports = { 31 | addUser, 32 | getUser 33 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-swagger-autogen", 3 | "version": "1.0.0", 4 | "description": "Example showing the use of the swagger-autogen module.", 5 | "main": "index.js", 6 | "readmeFilename": "README.md", 7 | "private": false, 8 | "keywords": [ 9 | "swagger", 10 | "autogen", 11 | "example" 12 | ], 13 | "author": { 14 | "name": "Davi D. Baltar", 15 | "email": "davibaltar.npm@gmail.com" 16 | }, 17 | "license": "MIT", 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/davibaltar/example-swagger-autogen.git" 21 | }, 22 | "scripts": { 23 | "start": "node index.js", 24 | "start-gendoc": "node swagger.js" 25 | }, 26 | "dependencies": { 27 | "express": "^4.17.1", 28 | "swagger-autogen": "^2.23.4", 29 | "swagger-ui-express": "^4.1.4" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Run the project and access the documentation at: http://localhost:3000/doc 3 | * 4 | * Use the command below to generate the documentation without starting the project: 5 | * $ npm start 6 | * 7 | * Use the command below to generate the documentation at project startup: 8 | * $ npm run start-gendoc 9 | */ 10 | 11 | 12 | const swaggerUi = require('swagger-ui-express') 13 | const swaggerFile = require('./swagger-output.json') 14 | const bodyParser = require('body-parser') 15 | const express = require('express') 16 | const app = express() 17 | 18 | /* Middlewares */ 19 | app.use(bodyParser.json()) 20 | app.use('/doc', swaggerUi.serve, swaggerUi.setup(swaggerFile)) 21 | 22 | app.listen(3000, () => { 23 | console.log("Server is running!\nAPI documentation: http://localhost:3000/doc") 24 | }) 25 | 26 | /* Endpoints */ 27 | require('./src/endpoints')(app) 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IDE files 2 | .idea 3 | 4 | # Logs 5 | logs 6 | log.* 7 | *.log 8 | 9 | # Runtime data 10 | pids 11 | *.pid 12 | *.seed 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | # Commenting this out is preferred by some people, see 28 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 29 | node_modules 30 | 31 | # Users Environment Variables 32 | .lock-wscript 33 | 34 | # Runtime configuration for swagger app 35 | config/runtime.yaml 36 | 37 | .vscode 38 | draft 39 | package-lock.json 40 | test/env.js 41 | .DS_Store 42 | tests -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 davibaltar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /swagger.js: -------------------------------------------------------------------------------- 1 | const swaggerAutogen = require('swagger-autogen')() 2 | 3 | 4 | const doc = { 5 | info: { 6 | version: "1.0.0", 7 | title: "My API", 8 | description: "Documentation automatically generated by the swagger-autogen module." 9 | }, 10 | host: "localhost:3000", 11 | basePath: "/", 12 | schemes: ['http', 'https'], 13 | consumes: ['application/json'], 14 | produces: ['application/json'], 15 | tags: [ 16 | { 17 | "name": "User", 18 | "description": "Endpoints" 19 | } 20 | ], 21 | securityDefinitions: { 22 | api_key: { 23 | type: "apiKey", 24 | name: "api_key", 25 | in: "header" 26 | }, 27 | petstore_auth: { 28 | type: "oauth2", 29 | authorizationUrl: "https://petstore.swagger.io/oauth/authorize", 30 | flow: "implicit", 31 | scopes: { 32 | read_pets: "read your pets", 33 | write_pets: "modify pets in your account" 34 | } 35 | } 36 | }, 37 | definitions: { 38 | Parents: { 39 | father: "Simon Doe", 40 | mother: "Marie Doe" 41 | }, 42 | User: { 43 | name: "Jhon Doe", 44 | age: 29, 45 | parents: { 46 | $ref: '#/definitions/Parents' 47 | }, 48 | diplomas: [ 49 | { 50 | school: "XYZ University", 51 | year: 2020, 52 | completed: true, 53 | internship: { 54 | hours: 290, 55 | location: "XYZ Company" 56 | } 57 | } 58 | ] 59 | }, 60 | AddUser: { 61 | $name: "Jhon Doe", 62 | $age: 29, 63 | about: "" 64 | } 65 | } 66 | } 67 | 68 | const outputFile = './swagger-output.json' 69 | const endpointsFiles = ['./src/endpoints.js'] 70 | 71 | swaggerAutogen(outputFile, endpointsFiles, doc).then(() => { 72 | require('./index') // Your project's root file 73 | }) -------------------------------------------------------------------------------- /src/endpoints.js: -------------------------------------------------------------------------------- 1 | 2 | const users = require('./users') 3 | let expression = true 4 | 5 | 6 | module.exports = function (app) { 7 | 8 | /* NOTE: 100% automatic */ 9 | app.get('/automatic/users/:id', (req, res) => { 10 | res.setHeader('Content-Type', 'application/json') 11 | const dataId = users.getUser(req.params.id) 12 | const dataObj = users.getUser(req.query.obj) 13 | 14 | if (expression) 15 | return res.status(200).send(true) 16 | return res.status(404).send(false) 17 | }) 18 | 19 | /* NOTE: 100% automatic */ 20 | app.post('/automatic/users', (req, res) => { 21 | res.setHeader('Content-Type', 'application/xml') 22 | const data = users.addUser(req.query.obj) 23 | 24 | if (expression) 25 | return res.status(201).send(data) 26 | return res.status(500) 27 | }) 28 | 29 | /* NOTE: Completing informations automaticaly obtaineds */ 30 | app.get('/automatic_and_incremented/users/:id', (req, res) => { 31 | /* #swagger.tags = ['User'] 32 | #swagger.description = 'Endpoint to get the specific user.' */ 33 | res.setHeader('Content-Type', 'application/json') 34 | const data = users.getUser(req.params.id) 35 | 36 | if (expression) { 37 | /* #swagger.responses[200] = { 38 | schema: { "$ref": "#/definitions/User" }, 39 | description: "User registered successfully." } */ 40 | return res.status(200).send(data) 41 | } 42 | return res.status(404).send(false) // #swagger.responses[404] 43 | }) 44 | 45 | /* NOTE: Completing informations automaticaly obtaineds */ 46 | app.post('/automatic_and_incremented/users', (req, res) => { 47 | res.setHeader('Content-Type', 'application/xml') 48 | /* #swagger.tags = ['User'] 49 | #swagger.description = 'Endpoint to add a user.' */ 50 | 51 | /* #swagger.parameters['obj'] = { 52 | in: 'body', 53 | description: 'User information.', 54 | required: true, 55 | schema: { $ref: "#/definitions/AddUser" } 56 | } */ 57 | const data = users.addUser(req.body) 58 | 59 | if (expression) { 60 | // #swagger.responses[201] = { description: 'User registered successfully.' } 61 | return res.status(201).send(data) 62 | } 63 | return res.status(500) 64 | }) 65 | 66 | /* NOTE: Function with callback referencied */ 67 | app.delete('/automatic_and_incremented/users/:id', myFunction1) 68 | 69 | /* NOTE: Will be ignored in the build */ 70 | app.get('/toIgnore', (req, res) => { 71 | // #swagger.ignore = true 72 | res.setHeader('Content-Type', 'application/json') 73 | 74 | if (expression) 75 | return res.status(200).send(true) 76 | return res.status(404).send(false) 77 | }) 78 | 79 | app.patch('/testmanual/users/:id', (req, res) => { 80 | /* #swagger.auto = false 81 | 82 | #swagger.path = '/manual/users/{id}' 83 | #swagger.method = 'patch' 84 | #swagger.description = 'Endpoint added manually.' 85 | #swagger.produces = ["application/json"] 86 | #swagger.consumes = ["application/json"] 87 | */ 88 | 89 | /* #swagger.parameters['id'] = { 90 | in: 'path', 91 | description: 'User ID.', 92 | required: true 93 | } 94 | */ 95 | 96 | /* #swagger.parameters['obj'] = { 97 | in: 'query', 98 | description: 'User information.', 99 | required: true, 100 | type: 'string' 101 | } 102 | */ 103 | 104 | if (expression) { 105 | /* #swagger.responses[200] = { 106 | schema: { "$ref": "#/definitions/User" }, description: "User found." } 107 | */ 108 | return res.status(200).send(data) 109 | } 110 | // #swagger.responses[500] = { description: "Server Failure." } 111 | return res.status(500).send(false) 112 | }) 113 | 114 | app.head('/security', (req, res) => { 115 | res.setHeader('Content-Type', 'application/json') 116 | /* #swagger.security = [{ 117 | "petstore_auth": [ 118 | "write_pets", 119 | "read_pets" 120 | ] 121 | }] */ 122 | 123 | const dataObj = users.getUser(req.query.obj) 124 | 125 | if (expression) 126 | return res.status(200).send(true) 127 | return res.status(404).send(false) 128 | }) 129 | } 130 | 131 | function myFunction1(req, res) { 132 | const dataId = users.getUser(req.params.id) 133 | 134 | if (expression) 135 | return res.status(200).send(true) 136 | return res.status(404).send(false) 137 | } 138 | 139 | -------------------------------------------------------------------------------- /swagger-output.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "version": "1.0.0", 5 | "title": "My API", 6 | "description": "Documentation automatically generated by the swagger-autogen module." 7 | }, 8 | "host": "localhost:3000", 9 | "basePath": "/", 10 | "tags": [ 11 | { 12 | "name": "User", 13 | "description": "Endpoints" 14 | } 15 | ], 16 | "schemes": [ 17 | "http", 18 | "https" 19 | ], 20 | "securityDefinitions": { 21 | "api_key": { 22 | "type": "apiKey", 23 | "name": "api_key", 24 | "in": "header" 25 | }, 26 | "petstore_auth": { 27 | "type": "oauth2", 28 | "authorizationUrl": "https://petstore.swagger.io/oauth/authorize", 29 | "flow": "implicit", 30 | "scopes": { 31 | "read_pets": "read your pets", 32 | "write_pets": "modify pets in your account" 33 | } 34 | } 35 | }, 36 | "consumes": [ 37 | "application/json" 38 | ], 39 | "produces": [ 40 | "application/json" 41 | ], 42 | "paths": { 43 | "/automatic/users/{id}": { 44 | "get": { 45 | "tags": [], 46 | "description": "", 47 | "produces": [ 48 | "application/json" 49 | ], 50 | "parameters": [ 51 | { 52 | "name": "id", 53 | "in": "path", 54 | "required": true, 55 | "type": "string" 56 | }, 57 | { 58 | "name": "obj", 59 | "in": "query", 60 | "type": "string" 61 | } 62 | ], 63 | "responses": { 64 | "200": { 65 | "description": "OK" 66 | }, 67 | "404": { 68 | "description": "Not Found" 69 | } 70 | } 71 | } 72 | }, 73 | "/automatic/users": { 74 | "post": { 75 | "tags": [], 76 | "description": "", 77 | "produces": [ 78 | "application/xml" 79 | ], 80 | "parameters": [ 81 | { 82 | "name": "obj", 83 | "in": "query", 84 | "type": "string" 85 | } 86 | ], 87 | "responses": { 88 | "201": { 89 | "description": "Created" 90 | }, 91 | "500": { 92 | "description": "Internal Server Error" 93 | } 94 | } 95 | } 96 | }, 97 | "/automatic_and_incremented/users/{id}": { 98 | "get": { 99 | "tags": [ 100 | "User" 101 | ], 102 | "description": "Endpoint to get the specific user.", 103 | "produces": [ 104 | "application/json" 105 | ], 106 | "parameters": [ 107 | { 108 | "name": "id", 109 | "in": "path", 110 | "required": true, 111 | "type": "string" 112 | } 113 | ], 114 | "responses": { 115 | "200": { 116 | "description": "User registered successfully.", 117 | "schema": { 118 | "$ref": "#/definitions/User" 119 | } 120 | }, 121 | "404": { 122 | "description": "Not Found" 123 | } 124 | } 125 | }, 126 | "delete": { 127 | "tags": [], 128 | "description": "", 129 | "parameters": [ 130 | { 131 | "name": "id", 132 | "in": "path", 133 | "required": true, 134 | "type": "string" 135 | } 136 | ], 137 | "responses": { 138 | "200": { 139 | "description": "OK" 140 | }, 141 | "404": { 142 | "description": "Not Found" 143 | } 144 | } 145 | } 146 | }, 147 | "/automatic_and_incremented/users": { 148 | "post": { 149 | "tags": [ 150 | "User" 151 | ], 152 | "description": "Endpoint to add a user.", 153 | "produces": [ 154 | "application/xml" 155 | ], 156 | "parameters": [ 157 | { 158 | "name": "obj", 159 | "in": "body", 160 | "description": "User information.", 161 | "required": true, 162 | "schema": { 163 | "$ref": "#/definitions/AddUser" 164 | } 165 | } 166 | ], 167 | "responses": { 168 | "201": { 169 | "description": "User registered successfully." 170 | }, 171 | "500": { 172 | "description": "Internal Server Error" 173 | } 174 | } 175 | } 176 | }, 177 | "/manual/users/{id}": { 178 | "patch": { 179 | "tags": [], 180 | "description": "Endpoint added manually.", 181 | "consumes": [ 182 | "application/json" 183 | ], 184 | "produces": [ 185 | "application/json" 186 | ], 187 | "parameters": [ 188 | { 189 | "name": "id", 190 | "in": "path", 191 | "description": "User ID.", 192 | "required": true, 193 | "type": "string" 194 | }, 195 | { 196 | "name": "obj", 197 | "in": "query", 198 | "description": "User information.", 199 | "required": true, 200 | "type": "string" 201 | } 202 | ], 203 | "responses": { 204 | "200": { 205 | "schema": { 206 | "$ref": "#/definitions/User" 207 | }, 208 | "description": "User found." 209 | }, 210 | "500": { 211 | "description": "Server Failure." 212 | } 213 | } 214 | } 215 | }, 216 | "/security": { 217 | "head": { 218 | "tags": [], 219 | "description": "", 220 | "produces": [ 221 | "application/json" 222 | ], 223 | "parameters": [ 224 | { 225 | "name": "obj", 226 | "in": "query", 227 | "type": "string" 228 | } 229 | ], 230 | "responses": { 231 | "200": { 232 | "description": "OK" 233 | }, 234 | "404": { 235 | "description": "Not Found" 236 | } 237 | }, 238 | "security": [ 239 | { 240 | "petstore_auth": [ 241 | "write_pets", 242 | "read_pets" 243 | ] 244 | } 245 | ] 246 | } 247 | } 248 | }, 249 | "definitions": { 250 | "Parents": { 251 | "type": "object", 252 | "properties": { 253 | "father": { 254 | "type": "string", 255 | "example": "Simon Doe" 256 | }, 257 | "mother": { 258 | "type": "string", 259 | "example": "Marie Doe" 260 | } 261 | }, 262 | "xml": { 263 | "name": "Parents" 264 | } 265 | }, 266 | "User": { 267 | "type": "object", 268 | "properties": { 269 | "name": { 270 | "type": "string", 271 | "example": "Jhon Doe" 272 | }, 273 | "age": { 274 | "type": "number", 275 | "example": 29 276 | }, 277 | "parents": { 278 | "xml": { 279 | "name": "parents" 280 | }, 281 | "$ref": "#/definitions/Parents" 282 | }, 283 | "diplomas": { 284 | "type": "array", 285 | "items": { 286 | "type": "object", 287 | "properties": { 288 | "school": { 289 | "type": "string", 290 | "example": "XYZ University" 291 | }, 292 | "year": { 293 | "type": "number", 294 | "example": 2020 295 | }, 296 | "completed": { 297 | "type": "boolean", 298 | "example": true 299 | }, 300 | "internship": { 301 | "type": "object", 302 | "properties": { 303 | "hours": { 304 | "type": "number", 305 | "example": 290 306 | }, 307 | "location": { 308 | "type": "string", 309 | "example": "XYZ Company" 310 | } 311 | } 312 | } 313 | } 314 | } 315 | } 316 | }, 317 | "xml": { 318 | "name": "User" 319 | } 320 | }, 321 | "AddUser": { 322 | "type": "object", 323 | "properties": { 324 | "name": { 325 | "type": "string", 326 | "example": "Jhon Doe" 327 | }, 328 | "age": { 329 | "type": "number", 330 | "example": 29 331 | }, 332 | "about": { 333 | "type": "string", 334 | "example": "" 335 | } 336 | }, 337 | "required": [ 338 | "name", 339 | "age" 340 | ], 341 | "xml": { 342 | "name": "AddUser" 343 | } 344 | } 345 | } 346 | } 347 | --------------------------------------------------------------------------------