Skip to content

Commit 37db5bf

Browse files
author
hirsch88
committed
Merge branch 'release/1.5.1'
2 parents 7ae5c58 + dac2345 commit 37db5bf

File tree

9 files changed

+362
-378
lines changed

9 files changed

+362
-378
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ A delightful way to building a RESTful API with NodeJs & TypeScript.
1111
- **Easy Data Seeding** with our own factories.
1212
- **Custom Commands** are also available in our setup and really easy to use.
1313
- **Smart Validation** thanks to [class-validator](https://github.com/pleerock/class-validator) with some nice annotations.
14+
- **Inline Swagger Documentation** thanks to [swagger-jsdoc](https://github.com/Surnet/swagger-jsdoc)
1415

1516
## Getting Started
1617
### Prerequisites

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "express-typescript-boilerplate",
3-
"version": "1.5.0",
3+
"version": "1.5.1",
44
"description": "A delightful way to building a RESTful API with NodeJs & TypeScript",
55
"main": "src/index.ts",
66
"scripts": {
@@ -104,6 +104,7 @@
104104
"require-dir": "^0.3.1",
105105
"run-sequence": "^1.2.2",
106106
"serve-favicon": "^2.4.3",
107+
"swagger-jsdoc": "^1.9.4",
107108
"swagger-ui-express": "^2.0.0",
108109
"ts-jest": "^20.0.4",
109110
"ts-node": "^3.0.4",

src/api/controllers/HomeController.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,23 @@ import { injectable } from 'inversify';
55
/**
66
* HomeController is a public controller to give some
77
* information about this api
8-
*
9-
* @export
10-
* @class HomeController
118
*/
129
@injectable()
13-
@Controller('/')
10+
@Controller('/v1')
1411
export class HomeController {
1512

13+
/**
14+
* @swagger
15+
* /:
16+
* get:
17+
* tags:
18+
* - Root
19+
* summary: Show API information
20+
* description: Gets the api information
21+
* responses:
22+
* 200:
23+
* description: api information
24+
*/
1625
@Get('/')
1726
public get( @Response() res: express.Response): any {
1827
const pkg = require('../../../package.json');

src/api/controllers/UserController.ts

Lines changed: 176 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,50 +11,223 @@ const log = new Log('api:ctrl.UserController');
1111
/**
1212
* UserController is in charge of the user resource and should
1313
* provide all crud actions.
14-
*
15-
* @export
16-
* @class UserController
1714
*/
1815
@injectable()
1916
@Controller('/v1/user', authenticate)
2017
export class UserController {
2118

2219
constructor( @inject(Types.UserService) private userService: UserService) { }
2320

21+
/**
22+
* @swagger
23+
* /user:
24+
* get:
25+
* tags:
26+
* - User
27+
* summary: List all users
28+
* description: Returns users
29+
* security:
30+
* - JWT: []
31+
* responses:
32+
* 200:
33+
* description: List of all users
34+
* schema:
35+
* type: object
36+
* title: UserResponse
37+
* properties:
38+
* success:
39+
* type: boolean
40+
* message:
41+
* type: string
42+
* data:
43+
* type: array
44+
* items:
45+
* $ref: "#/definitions/User"
46+
*/
2447
@Get('/')
2548
public async findAll( @Response() res: my.Response): Promise<any> {
2649
log.debug('findAll');
2750
const users = await this.userService.findAll();
2851
return res.found(users.toJSON());
2952
}
3053

54+
/**
55+
* @swagger
56+
* /user:
57+
* post:
58+
* tags:
59+
* - User
60+
* summary: Create new user
61+
* description: Creates new user and returns him
62+
* security:
63+
* - JWT: []
64+
* parameters:
65+
* - in: "body"
66+
* name: "body"
67+
* required: true
68+
* schema:
69+
* $ref: "#/definitions/NewUser"
70+
* responses:
71+
* 200:
72+
* description: New user
73+
* schema:
74+
* type: object
75+
* title: UserResponse
76+
* properties:
77+
* success:
78+
* type: boolean
79+
* message:
80+
* type: string
81+
* data:
82+
* $ref: "#/definitions/User"
83+
*/
3184
@Post('/')
3285
public async create( @Response() res: my.Response, @RequestBody() body: any): Promise<any> {
3386
log.debug('create ', body);
3487
const user = await this.userService.create(body);
3588
return res.created(user.toJSON());
3689
}
3790

91+
/**
92+
* @swagger
93+
* /user/me:
94+
* get:
95+
* tags:
96+
* - User
97+
* summary: Get logged in user
98+
* description: Returns logged in user
99+
* security:
100+
* - JWT: []
101+
* responses:
102+
* 200:
103+
* description: User
104+
* schema:
105+
* type: object
106+
* title: UserResponse
107+
* properties:
108+
* success:
109+
* type: boolean
110+
* message:
111+
* type: string
112+
* data:
113+
* type: object
114+
* $ref: "#/definitions/User"
115+
*/
38116
@Get('/me', populateUser)
39117
public async findMe( @Request() req: my.Request, @Response() res: my.Response): Promise<any> {
40118
log.debug('findMe');
41119
return res.found(req.user);
42120
}
43121

122+
/**
123+
* @swagger
124+
* /user/{id}:
125+
* get:
126+
* tags:
127+
* - User
128+
* summary: Get user
129+
* description: Returns a user
130+
* security:
131+
* - JWT: []
132+
* responses:
133+
* 200:
134+
* description: User
135+
* schema:
136+
* type: object
137+
* title: UserResponse
138+
* properties:
139+
* success:
140+
* type: boolean
141+
* message:
142+
* type: string
143+
* data:
144+
* type: object
145+
* $ref: "#/definitions/User"
146+
*/
44147
@Get('/:id')
45148
public async findOne( @Response() res: my.Response, @RequestParam('id') id: string): Promise<any> {
46149
log.debug('findOne ', id);
47150
const user = await this.userService.findOne(parseInt(id, 10));
48151
return res.found(user.toJSON());
49152
}
50153

154+
/**
155+
* @swagger
156+
* /user/{id}:
157+
* put:
158+
* tags:
159+
* - User
160+
* summary: Update user
161+
* description: Returns a user
162+
* security:
163+
* - JWT: []
164+
* parameters:
165+
* - name: "id"
166+
* in: "path"
167+
* description: "ID of user to return"
168+
* required: true
169+
* type: "integer"
170+
* format: "int64"
171+
* - in: "body"
172+
* name: "body"
173+
* description: "User object"
174+
* required: true
175+
* schema:
176+
* $ref: "#/definitions/NewUser"
177+
* responses:
178+
* 200:
179+
* description: User
180+
* schema:
181+
* type: object
182+
* title: UserResponse
183+
* properties:
184+
* success:
185+
* type: boolean
186+
* message:
187+
* type: string
188+
* data:
189+
* type: object
190+
* $ref: "#/definitions/User"
191+
*/
51192
@Put('/:id')
52193
public async update( @Response() res: my.Response, @RequestParam('id') id: string, @RequestBody() body: any): Promise<any> {
53194
log.debug('update ', body);
54195
const user = await this.userService.update(parseInt(id, 10), body);
55196
return res.updated(user.toJSON());
56197
}
57198

199+
/**
200+
* @swagger
201+
* /user/{id}:
202+
* delete:
203+
* tags:
204+
* - User
205+
* summary: Delete user
206+
* description: Returns a user
207+
* security:
208+
* - JWT: []
209+
* parameters:
210+
* - name: "id"
211+
* in: "path"
212+
* description: "ID of user to return"
213+
* required: true
214+
* type: "integer"
215+
* format: "int64"
216+
* responses:
217+
* 200:
218+
* description: User
219+
* schema:
220+
* type: object
221+
* title: UserResponse
222+
* properties:
223+
* success:
224+
* type: boolean
225+
* message:
226+
* type: string
227+
* data:
228+
* type: object
229+
* example:
230+
*/
58231
@Delete('/:id')
59232
public async destroy( @Response() res: my.Response, @RequestParam('id') id: string): Promise<any> {
60233
log.debug('destroy ', id);

src/api/models/User.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,43 @@ export class User extends Bookshelf.Model<User> {
4545

4646
}
4747

48+
/**
49+
* @swagger
50+
* definitions:
51+
* NewUser:
52+
* type: object
53+
* properties:
54+
* firstName:
55+
* type: string
56+
* lastName:
57+
* type: string
58+
* email:
59+
* type: string
60+
* picture:
61+
* type: string
62+
*/
63+
64+
/**
65+
* @swagger
66+
* definitions:
67+
* User:
68+
* type: object
69+
* properties:
70+
* id:
71+
* type: "integer"
72+
* format: "int64"
73+
* firstName:
74+
* type: string
75+
* lastName:
76+
* type: string
77+
* email:
78+
* type: string
79+
* picture:
80+
* type: string
81+
* updatedAt:
82+
* type: string
83+
* format: date-time
84+
* createdAt:
85+
* type: string
86+
* format: date-time
87+
*/

src/core/Bootstrap.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,31 @@ export class Bootstrap {
7979
*/
8080
static setupSwagger(app: express.Application): express.Application {
8181
if (Environment.get<string>('SWAGGER_ENABLED') === 'true') {
82-
const basePath = __dirname.substring(0, __dirname.indexOf('/src/') + 4);
82+
const swaggerJSDoc = require('swagger-jsdoc');
83+
const basePath = __dirname.substring(0, __dirname.indexOf('/src/'));
84+
85+
const swaggerDefinition = require(basePath + '/swagger.json');
86+
const packageJson = require(basePath + '/package.json');
87+
swaggerDefinition.info = {
88+
title: packageJson.name,
89+
description: packageJson.description,
90+
version: packageJson.version
91+
};
92+
93+
const options = {
94+
swaggerDefinition: swaggerDefinition,
95+
apis: [
96+
'./src/api/models/**/*.ts',
97+
'./src/api/controllers/**/*.ts'
98+
]
99+
};
100+
101+
// Initialize swagger-jsdoc -> returns validated swagger spec in json format
102+
const swaggerSpec = swaggerJSDoc(options);
83103
const swaggerUi = require('swagger-ui-express');
84-
const swaggerDocument = require(basePath + Environment.get<string>('SWAGGER_FILE'));
85104
const route = Environment.get<string>('APP_URL_PREFIX') + Environment.get<string>('SWAGGER_ROUTE');
86-
app.use(route, swaggerUi.serve, swaggerUi.setup(swaggerDocument));
105+
106+
app.use(route, swaggerUi.serve, swaggerUi.setup(swaggerSpec));
87107
log.info(`Now you can access the swagger docs under -> ${app.get('host')}:${(app.get('port'))}${route}`);
88108
}
89109
return app;

0 commit comments

Comments
 (0)