From 8b3c89cf0cb4295895c22c4c715a7f7b6edf0696 Mon Sep 17 00:00:00 2001 From: AbdulBasit KABIR Date: Thu, 5 Apr 2018 00:35:13 +0100 Subject: [PATCH 1/2] Add swagger doc --- README.md | 6 +- server/docs/definitions.yaml | 61 +++++++++++++++++++ server/docs/index.html | 91 ++++++++++++++++++++++++++++ server/docs/index.js | 41 +++++++++++++ server/docs/parameters.yaml | 32 ++++++++++ server/docs/responses.yaml | 28 +++++++++ server/docs/securityDefinitions.yaml | 9 +++ server/routes/event.route.js | 32 ++++++++++ server/routes/index.route.js | 21 +++++++ 9 files changed, 319 insertions(+), 2 deletions(-) create mode 100644 server/docs/definitions.yaml create mode 100644 server/docs/index.html create mode 100644 server/docs/index.js create mode 100644 server/docs/parameters.yaml create mode 100644 server/docs/responses.yaml create mode 100644 server/docs/securityDefinitions.yaml diff --git a/README.md b/README.md index bcdda56..d26c944 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,8 @@ loginEvent: (username) => { deviceType: 'Browser', eventTime: new Date().getTime(), eventType: 'login', - eventData: {} + eventData: {}, + eventApiEnv: `${EVENT_API_ENV}` }) } ``` @@ -62,7 +63,8 @@ playEpisodeEvent: (username, playEvent) => { episodeName: playEvent.episodeName, minutesPlayed: playEvent.minutesPlayed, minutesRemaining: playEvent.minutesRemaining - } + }, + eventApiEnv: `${EVENT_API_ENV}` }) } ``` diff --git a/server/docs/definitions.yaml b/server/docs/definitions.yaml new file mode 100644 index 0000000..8df871b --- /dev/null +++ b/server/docs/definitions.yaml @@ -0,0 +1,61 @@ +definitions: + Error: + type: object + properties: + message: + type: string + description: Reason for error + example: Error message + stack: + type: string + description: Stack trace resulting in error + Event: + type: object + properties: + clientId: + type: string + description: Id of user initiating event + example: user01 + deviceType: + type: string + description: type of device where the event originates + enum: [iOS, Android, Browser, API] + example: Android + eventApiEnv: + type: string + description: environment where the event originates + enum: [production, test] + example: test + eventTime: + type: string + format: unix-time + description: valid timestamp of when event is triggered + example: 1522767185 + eventData: + type: object + description: raw data of the event being streamed + eventType: + type: string + description: type of event being streamed + enum: [register, + login, + logout, + playEpisode, + pauseEpisode, + likeEpisode, + completedEpisode, + fastForwardEpisode, + rewindEpisode, + seekEpisode, + searchEpisode] + required: + - clientId + - deviceType + - eventApiEnv + - eventTime + - eventData + - eventType + Token: + type: string + description: JSON web token to store credentials + example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1OWY4Njc3YzFkNmZmZDNkMGJkODMzNGIiLCJwYXNzd29yZCI6IiQyYSQwOCRoMEgyR2FWbWh1V0tNd1hSWlRYekxPcDMuWG85OGJmYVZYWXp2cURuU2p1SGlrZE9YRmd3LiIsInVzZXJuYW1lIjoiam9obkBqYWNvYi5jb20iLCJfX3YiOjAsImNyZWF0ZWRBdCI6IjIwMTctMTAtMzFUMTI6MDc6MjQuNTAyWiIsImlhdCI6MTUwOTQ1Mjk0MywiZXhwIjoxNjUzNDUyOTQzfQ.2yECxNnmM6u9wcUkYq1OPX6HzfcLeaOgoQ35PJ2fQZs \ No newline at end of file diff --git a/server/docs/index.html b/server/docs/index.html new file mode 100644 index 0000000..cb331f1 --- /dev/null +++ b/server/docs/index.html @@ -0,0 +1,91 @@ + + + + + + + SED API Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + \ No newline at end of file diff --git a/server/docs/index.js b/server/docs/index.js new file mode 100644 index 0000000..f9ef0dd --- /dev/null +++ b/server/docs/index.js @@ -0,0 +1,41 @@ +const swaggerJSDoc = require('swagger-jsdoc'); +const express = require('express'); + +const router = express.Router(); // eslint-disable-line new-cap + +// Swagger definition aka OpenAPI v2.0 +// https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md + +const swaggerDefinition = { + info: { + // API information (required) + title: 'SEDaily DevOps', // Title (required) + version: '1.0.0', // Version (required) + description: 'Software Engineering Daily Logging, Monitoring, and Analytics API Documentation. You can use these by not only browsing the API routes, but also by executing requests against the server.' + }, + basePath: '/api/v1', + produces: ['application/json'], + consumes: ['application/json'], +}; + +const options = { + swaggerDefinition, + apis: [ + // controllers include parameters, tags and paths + './server/controllers/*.js', + // a few "general" paths are defined in index + './server/routes/*.route.js', + // responses, securityDefinitions and general definitions/parameters in separate yaml + './server/docs/*.yaml', + ] +}; +const swaggerSpec = swaggerJSDoc(options); + +router.get('/swagger.json', (req, res) => { + res.setHeader('Content-Type', 'application/json'); + res.send(swaggerSpec); +}); + +router.use('/', express.static(__dirname)); + +module.exports = router; diff --git a/server/docs/parameters.yaml b/server/docs/parameters.yaml new file mode 100644 index 0000000..b00871e --- /dev/null +++ b/server/docs/parameters.yaml @@ -0,0 +1,32 @@ +parameters: + limit: + name: limit + in: query + description: max items to return + required: false + type: integer + skip: + name: skip + in: query + description: number of items to skip + required: false + type: integer + default: 0 + userParam: + name: loginUser + in: body + description: User to register/login with + type: object + properties: + username: + type: string + description: User name + example: johnjacob + password: + type: string + format: password + description: Clear-text password + example: secret + required: + - username + - password diff --git a/server/docs/responses.yaml b/server/docs/responses.yaml new file mode 100644 index 0000000..efd62c3 --- /dev/null +++ b/server/docs/responses.yaml @@ -0,0 +1,28 @@ +responses: + NotFound: + description: The specified resource was not found + schema: + $ref: '#/definitions/Error' + Unauthorized: + description: Unauthorized + schema: + $ref: '#/definitions/Error' + BadRequest: + description: Bad request - missing required elements + schema: + $ref: '#/definitions/Error' + SuccessfulAuthentication: + description: Successful authentication + schema: + type: object + properties: + token: + $ref: '#/definitions/Token' + Success: + description: successful operation + schema: + type: object + properties: + result: + type: string + enum: 'success' diff --git a/server/docs/securityDefinitions.yaml b/server/docs/securityDefinitions.yaml new file mode 100644 index 0000000..d3acd51 --- /dev/null +++ b/server/docs/securityDefinitions.yaml @@ -0,0 +1,9 @@ +securityDefinitions: + Token: + description: | + For accessing the protected API resources, you must have received a a valid JWT token after registering or logging in. This JWT token must then be used for all protected resources by passing it in via the 'Authorization' header. + + A JWT token is generated by the API by either registering via /auth/register or logging in via /auth/login. + type: apiKey + name: Authorization + in: header diff --git a/server/routes/event.route.js b/server/routes/event.route.js index ed713b4..8c1176a 100644 --- a/server/routes/event.route.js +++ b/server/routes/event.route.js @@ -8,6 +8,38 @@ const router = express.Router(); // Disabling validation for now // router.use(expressJwt({ secret: config.jwtSecret })); +/** + * @swagger + * tags: + * - name: event + * description: Sending user events + */ + +/** + * @swagger + * /event: + * post: + * summary: Stream an event + * description: Stream an event + * tags: [event] + * parameters: + * - in: body + * name: event + * schema: + * $ref: '#/definitions/Event' + * required: true + * description: Event to stream + * responses: + * '200': + * $ref: '#/responses/Success' + * '400': + * $ref: '#/responses/BadRequest' + * '401': + * $ref: '#/responses/Unauthorized' + * '404': + * $ref: '#/responses/NotFound' + */ + router.route('/') .post(validate(paramValidation.event), eventCtrl.validateEventType, eventCtrl.newEvent); diff --git a/server/routes/index.route.js b/server/routes/index.route.js index 90bd2cf..d670b38 100644 --- a/server/routes/index.route.js +++ b/server/routes/index.route.js @@ -1,13 +1,34 @@ import express from 'express'; import eventRoutes from './event.route'; import errorRoutes from './error.route'; +import docRoutes from '../docs'; const router = express.Router(); // eslint-disable-line new-cap +/** + * @swagger + * tags: + * - name: general + * description: General/server-related + */ + +/** + * @swagger + * /health-check: + * get: + * summary: Health check of server + * description: Confirm SED API server running and okay + * tags: [general] + * responses: + * 200: + * description: successful operation + */ + router.get('/health-check', (req, res) => res.send('OK')); router.use('/event', eventRoutes); router.use('/error', errorRoutes); +router.use('/docs', docRoutes); export default router; From 6438c41f61f432cbe08c617e8363d2d7c2277369 Mon Sep 17 00:00:00 2001 From: AbdulBasit KABIR Date: Sun, 8 Apr 2018 12:30:10 +0100 Subject: [PATCH 2/2] remove parameters.yaml file --- server/docs/parameters.yaml | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 server/docs/parameters.yaml diff --git a/server/docs/parameters.yaml b/server/docs/parameters.yaml deleted file mode 100644 index b00871e..0000000 --- a/server/docs/parameters.yaml +++ /dev/null @@ -1,32 +0,0 @@ -parameters: - limit: - name: limit - in: query - description: max items to return - required: false - type: integer - skip: - name: skip - in: query - description: number of items to skip - required: false - type: integer - default: 0 - userParam: - name: loginUser - in: body - description: User to register/login with - type: object - properties: - username: - type: string - description: User name - example: johnjacob - password: - type: string - format: password - description: Clear-text password - example: secret - required: - - username - - password