From feee6d41b8c43dcd81ba3676261c9e9527421687 Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 20:51:37 -0500 Subject: [PATCH 01/18] Add generated `docs` dir to gitnore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 764e940..8a4d14a 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,6 @@ node_modules # sftp configuration file sftp-config.json + +#Documentation +docs From 5c0cec3d9cf24e1343d09e48a8a6e5544f3646d5 Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 21:01:13 -0500 Subject: [PATCH 02/18] Add apidoc config --- apidoc.json | 7 +++++++ package.json | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 apidoc.json diff --git a/apidoc.json b/apidoc.json new file mode 100644 index 0000000..0560858 --- /dev/null +++ b/apidoc.json @@ -0,0 +1,7 @@ +{ + "name": "koa2-api-boilerplate", + "version": "1.1.0", + "description": "Koa2 boilerplate covering essentials for APIs", + "title": "koa2-api-boilerplate", + "url" : "https://github.com/adrianObel/koa2-api-boilerplate" +} diff --git a/package.json b/package.json index 49d3c76..cfb8943 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "start": "node index.js", "dev": "./node_modules/.bin/nodemon index.js", "test": "NODE_ENV=test ./node_modules/.bin/mocha --compilers js:babel-register --require babel-polyfill", - "lint": "eslint src/**/*.js" + "lint": "eslint src/**/*.js", + "docs": "./node_modules/.bin/apidoc -i src/ -o docs" }, "keywords": [ "koa2-api-boilerplate", @@ -40,6 +41,7 @@ "passport-local": "^1.0.0" }, "devDependencies": { + "apidoc": "^0.15.1", "babel-eslint": "^4.1.8", "babel-register": "^6.5.1", "chai": "^3.5.0", From 996d1a541e2bd97e92ed32004c919be28bc4d787 Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 21:04:14 -0500 Subject: [PATCH 03/18] Move apidoc config to package.json --- apidoc.json | 7 ------- package.json | 8 ++++++++ 2 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 apidoc.json diff --git a/apidoc.json b/apidoc.json deleted file mode 100644 index 0560858..0000000 --- a/apidoc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "koa2-api-boilerplate", - "version": "1.1.0", - "description": "Koa2 boilerplate covering essentials for APIs", - "title": "koa2-api-boilerplate", - "url" : "https://github.com/adrianObel/koa2-api-boilerplate" -} diff --git a/package.json b/package.json index cfb8943..14190ef 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,14 @@ ], "author": "Adrian Obelmejias ", "license": "MIT", + "apidoc": { + "title": "koa2-api-boilerplate", + "url" : "https://github.com/adrianObel/koa2-api-boilerplate" + }, + "repository": { + "type": "git", + "url": "https://github.com/adrianObel/koa2-api-boilerplate" + }, "dependencies": { "babel-core": "^6.5.1", "babel-polyfill": "^6.5.0", From 7a81625c402aeb83a76e11de1533c1220966ab89 Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 21:55:18 -0500 Subject: [PATCH 04/18] Add documentation for authentication route --- src/controllers/auth.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/controllers/auth.js b/src/controllers/auth.js index 3a66471..0089a3b 100644 --- a/src/controllers/auth.js +++ b/src/controllers/auth.js @@ -5,6 +5,37 @@ import config from '../../config/config' const router = new Router({ prefix: '/auth' }) + +/** + * @api {post} /auth Authenticate user + * @apiVersion 1.0.0 + * @apiName AuthUser + * @apiGroup Auth + * + * @apiParam {String} email User email. + * @apiParam {String} password User password. + * + * @apiSuccess {String} firstname Firstname of the User. + * @apiSuccess {String} lastname Lastname of the User. + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "user": { + * "username": "johndoe" + * }, + * "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ" + * } + * + * @apiError UserNotFound The id of the User was not found. + * + * @apiErrorExample {json} Error-Response: + * HTTP/1.1 401 Unauthorized + * { + * "status": 401, + * "error": "Unauthorized" + * } + */ router.post('/', async (ctx, next) => passport.authenticate('local', (user) => { if (!user) { From ec2b1be7a6ca6551570f65f7e43a540b75573f41 Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 22:25:44 -0500 Subject: [PATCH 05/18] Update dependencies --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 14190ef..3042d2f 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "license": "MIT", "apidoc": { "title": "koa2-api-boilerplate", - "url" : "https://github.com/adrianObel/koa2-api-boilerplate" + "url": "localhost:5000" }, "repository": { "type": "git", @@ -45,6 +45,7 @@ "koa-logger": "^1.3.0", "koa-passport": "^2.0.1", "koa-router": "^7.0.1", + "koa-static": "^2.0.0", "mongoose": "^4.4.3", "passport-local": "^1.0.0" }, From f8504f86ba18ea69763bea5953b6818121bd9285 Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 22:26:21 -0500 Subject: [PATCH 06/18] Update auth docs --- src/controllers/auth.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/controllers/auth.js b/src/controllers/auth.js index 0089a3b..589573f 100644 --- a/src/controllers/auth.js +++ b/src/controllers/auth.js @@ -12,22 +12,30 @@ const router = new Router({ prefix: '/auth' }) * @apiName AuthUser * @apiGroup Auth * - * @apiParam {String} email User email. - * @apiParam {String} password User password. + * @apiParam {String} username User username. + * @apiParam {String} password User password. * - * @apiSuccess {String} firstname Firstname of the User. - * @apiSuccess {String} lastname Lastname of the User. + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X POST -d '{ "username": "johndoe@gmail.com", "password": "foo" }' localhost:5000/auth + * + * @apiSuccess {Object} user User object + * @apiSuccess {ObjectId} user._id User id + * @apiSuccess {String} user.name User name + * @apiSuccess {String} user.username User username + * @apiSuccess {String} token Encoded JWT * * @apiSuccessExample {json} Success-Response: * HTTP/1.1 200 OK * { * "user": { + * "_id": "56bd1da600a526986cf65c80" + * "username": "foo" * "username": "johndoe" * }, * "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ" * } * - * @apiError UserNotFound The id of the User was not found. + * @apiError Unauthorized Incorrect credentials * * @apiErrorExample {json} Error-Response: * HTTP/1.1 401 Unauthorized From f2183f990417fc2c5675676a54b5dc30aaa69fc6 Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 22:27:33 -0500 Subject: [PATCH 07/18] Move `server.js` entrypoint to `bin` directory --- {config => bin}/server.js | 2 ++ index.js | 2 +- test/users.spec.js | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) rename {config => bin}/server.js (90%) diff --git a/config/server.js b/bin/server.js similarity index 90% rename from config/server.js rename to bin/server.js index 5240725..a707fc2 100644 --- a/config/server.js +++ b/bin/server.js @@ -5,6 +5,7 @@ import logger from 'koa-logger' import mongoose from 'mongoose' import session from 'koa-generic-session' import passport from 'koa-passport' +import serve from 'koa-static' import config from './config' import { errorMiddleware } from '../src/middleware' @@ -18,6 +19,7 @@ app.use(convert(logger())) app.use(convert(bodyParser())) app.use(convert(session())) app.use(errorMiddleware()) +app.use(convert(serve(`${process.cwd()}/docs/`))) require('./passport') app.use(passport.initialize()) diff --git a/index.js b/index.js index e6e40e9..6f34cc9 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,3 @@ require("babel-core/register")(); require("babel-polyfill"); -require('./config/server.js'); +require('./bin/server.js'); diff --git a/test/users.spec.js b/test/users.spec.js index 8f880ea..0fe356f 100644 --- a/test/users.spec.js +++ b/test/users.spec.js @@ -1,4 +1,4 @@ -import app from '../config/server' +import app from '../bin/server' import supertest from 'supertest' import { expect, should } from 'chai' import { cleanDb } from './utils' From 5aea701513f02f216a5721af5e5547fbef7a1dc6 Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 22:40:39 -0500 Subject: [PATCH 08/18] Change `config/config.js` to a default `config/index.js` --- bin/server.js | 9 ++++----- config/{config.js => index.js} | 0 src/controllers/auth.js | 2 +- src/controllers/users.js | 2 +- src/middleware/index.js | 13 +++++++++++++ 5 files changed, 19 insertions(+), 7 deletions(-) rename config/{config.js => index.js} (100%) diff --git a/bin/server.js b/bin/server.js index a707fc2..e207208 100644 --- a/bin/server.js +++ b/bin/server.js @@ -5,10 +5,9 @@ import logger from 'koa-logger' import mongoose from 'mongoose' import session from 'koa-generic-session' import passport from 'koa-passport' -import serve from 'koa-static' -import config from './config' -import { errorMiddleware } from '../src/middleware' +import config from '../config' +import { errorMiddleware, docs } from '../src/middleware' const app = new Koa() app.keys = [config.session] @@ -19,9 +18,9 @@ app.use(convert(logger())) app.use(convert(bodyParser())) app.use(convert(session())) app.use(errorMiddleware()) -app.use(convert(serve(`${process.cwd()}/docs/`))) +app.use(docs()) -require('./passport') +require('../config/passport') app.use(passport.initialize()) app.use(passport.session()) diff --git a/config/config.js b/config/index.js similarity index 100% rename from config/config.js rename to config/index.js diff --git a/src/controllers/auth.js b/src/controllers/auth.js index 589573f..9d64e04 100644 --- a/src/controllers/auth.js +++ b/src/controllers/auth.js @@ -1,7 +1,7 @@ import Router from 'koa-router' import passport from 'koa-passport' import jwt from 'jsonwebtoken' -import config from '../../config/config' +import config from '../../config' const router = new Router({ prefix: '/auth' }) diff --git a/src/controllers/users.js b/src/controllers/users.js index 1819ce6..a104d4e 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -1,6 +1,6 @@ import Router from 'koa-router' import User from '../models/users' -import config from '../../config/config' +import config from '../../config' import jwt from 'jsonwebtoken' import { ensureUser } from '../middleware/validators' diff --git a/src/middleware/index.js b/src/middleware/index.js index 4f26450..f2a25df 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -1,3 +1,6 @@ +import convert from 'koa-convert' +import serve from 'koa-static' + export function errorMiddleware() { return async (ctx, next) => { try { @@ -9,3 +12,13 @@ export function errorMiddleware() { } } } + +export function docs() { + return async (ctx, next) => { + if(ctx.path !== '/docs') { + return next() + } + + await convert(serve(`${process.cwd()}/docs/`))(); + } +} From 0b16b62261026ec8f06d0b2c6724a942016d3a4e Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 23:05:31 -0500 Subject: [PATCH 09/18] Clean up dependencies --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 3042d2f..19d3c63 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "koa-convert": "^1.2.0", "koa-generic-session": "^1.10.1", "koa-logger": "^1.3.0", + "koa-mount": "^1.3.0", "koa-passport": "^2.0.1", "koa-router": "^7.0.1", "koa-static": "^2.0.0", From 87ea94b739592d46f44216bf1a58f9bd4ba4b310 Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 23:05:54 -0500 Subject: [PATCH 10/18] Mount documentation on `/docs` --- bin/server.js | 7 +++++-- src/middleware/index.js | 13 ------------- src/middleware/validators.js | 2 +- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/bin/server.js b/bin/server.js index e207208..cd425eb 100644 --- a/bin/server.js +++ b/bin/server.js @@ -5,9 +5,11 @@ import logger from 'koa-logger' import mongoose from 'mongoose' import session from 'koa-generic-session' import passport from 'koa-passport' +import mount from 'koa-mount' +import serve from 'koa-static' import config from '../config' -import { errorMiddleware, docs } from '../src/middleware' +import { errorMiddleware } from '../src/middleware' const app = new Koa() app.keys = [config.session] @@ -18,7 +20,8 @@ app.use(convert(logger())) app.use(convert(bodyParser())) app.use(convert(session())) app.use(errorMiddleware()) -app.use(docs()) + +app.use(convert(mount('/docs', serve(`${process.cwd()}/docs`)))) require('../config/passport') app.use(passport.initialize()) diff --git a/src/middleware/index.js b/src/middleware/index.js index f2a25df..4f26450 100644 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -1,6 +1,3 @@ -import convert from 'koa-convert' -import serve from 'koa-static' - export function errorMiddleware() { return async (ctx, next) => { try { @@ -12,13 +9,3 @@ export function errorMiddleware() { } } } - -export function docs() { - return async (ctx, next) => { - if(ctx.path !== '/docs') { - return next() - } - - await convert(serve(`${process.cwd()}/docs/`))(); - } -} diff --git a/src/middleware/validators.js b/src/middleware/validators.js index d7a76c9..1f35776 100644 --- a/src/middleware/validators.js +++ b/src/middleware/validators.js @@ -1,5 +1,5 @@ import User from '../models/users' -import config from '../../config/config' +import config from '../../config' import { verify } from 'jsonwebtoken' export async function ensureUser(ctx, next) { From 1eae3a4c0ebf4ca9344c59ef40c067baf925a56e Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 23:17:12 -0500 Subject: [PATCH 11/18] Define auth error --- src/controllers/auth.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/controllers/auth.js b/src/controllers/auth.js index 9d64e04..5616701 100644 --- a/src/controllers/auth.js +++ b/src/controllers/auth.js @@ -5,6 +5,17 @@ import config from '../../config' const router = new Router({ prefix: '/auth' }) +/** + * @apiDefine TokenError + * @apiError Unauthorized Invalid JWT token + * + * @apiErrorExample {json} Error-Response: + * HTTP/1.1 401 Unauthorized + * { + * "status": 401, + * "error": "Unauthorized" + * } + */ /** * @api {post} /auth Authenticate user From 1b026949d2796582109a896d96e1431d1fb8e4ba Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 23:23:25 -0500 Subject: [PATCH 12/18] Add docs for `GET /user/:id` --- src/controllers/users.js | 54 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/controllers/users.js b/src/controllers/users.js index a104d4e..264d446 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -6,6 +6,33 @@ import { ensureUser } from '../middleware/validators' const router = new Router({ prefix: '/users' }) +/** + * @api {get} /users Get all users + * @apiPermission user + * @apiVersion 1.0.0 + * @apiName GetUsers + * @apiGroup Users + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X GET localhost:5000/users + * + * @apiSuccess {Object[]} users Array of user objects + * @apiSuccess {ObjectId} users._id User id + * @apiSuccess {String} users.name User name + * @apiSuccess {String} users.username User username + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "users": [{ + * "_id": "56bd1da600a526986cf65c80" + * "username": "foo" + * "username": "johndoe" + * }] + * } + * + * @apiUse TokenError + */ router.get('/', ensureUser, async (ctx) => { @@ -14,6 +41,33 @@ router.get('/', } ) +/** + * @api {get} /users/:id Get user by id + * @apiPermission user + * @apiVersion 1.0.0 + * @apiName GetUser + * @apiGroup Users + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X GET localhost:5000/users/56bd1da600a526986cf65c80 + * + * @apiSuccess {Object} users User object + * @apiSuccess {ObjectId} users._id User id + * @apiSuccess {String} users.name User name + * @apiSuccess {String} users.username User username + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "user": { + * "_id": "56bd1da600a526986cf65c80" + * "username": "foo" + * "username": "johndoe" + * } + * } + * + * @apiUse TokenError + */ router.get('/:id', ensureUser, async (ctx) => { From f5bfba49c5578f50d045246254046586c560d2e7 Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 23:33:46 -0500 Subject: [PATCH 13/18] Add docs for `POST /users` --- src/controllers/users.js | 58 +++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/src/controllers/users.js b/src/controllers/users.js index 264d446..5467636 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -16,17 +16,17 @@ const router = new Router({ prefix: '/users' }) * @apiExample Example usage: * curl -H "Content-Type: application/json" -X GET localhost:5000/users * - * @apiSuccess {Object[]} users Array of user objects - * @apiSuccess {ObjectId} users._id User id - * @apiSuccess {String} users.name User name - * @apiSuccess {String} users.username User username + * @apiSuccess {Object[]} users Array of user objects + * @apiSuccess {ObjectId} users._id User id + * @apiSuccess {String} users.name User name + * @apiSuccess {String} users.username User username * * @apiSuccessExample {json} Success-Response: * HTTP/1.1 200 OK * { * "users": [{ * "_id": "56bd1da600a526986cf65c80" - * "username": "foo" + * "name": "John Doe" * "username": "johndoe" * }] * } @@ -51,17 +51,17 @@ router.get('/', * @apiExample Example usage: * curl -H "Content-Type: application/json" -X GET localhost:5000/users/56bd1da600a526986cf65c80 * - * @apiSuccess {Object} users User object - * @apiSuccess {ObjectId} users._id User id - * @apiSuccess {String} users.name User name - * @apiSuccess {String} users.username User username + * @apiSuccess {Object} users User object + * @apiSuccess {ObjectId} users._id User id + * @apiSuccess {String} users.name User name + * @apiSuccess {String} users.username User username * * @apiSuccessExample {json} Success-Response: * HTTP/1.1 200 OK * { * "user": { * "_id": "56bd1da600a526986cf65c80" - * "username": "foo" + * "name": "John Doe" * "username": "johndoe" * } * } @@ -88,6 +88,44 @@ router.get('/:id', } ) +/** + * @api {post} /users Create a new user + * @apiPermission + * @apiVersion 1.0.0 + * @apiName CreateUser + * @apiGroup Users + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X POST -d '{ "user": { "username": "johndoe", "password": "secretpasas" } }' localhost:5000/users + * + * @apiParam {Object} user User object (required) + * @apiParam {String} user.username Username. + * @apiParam {String} user.password Password. + * + * @apiSuccess {Object} users User object + * @apiSuccess {ObjectId} users._id User id + * @apiSuccess {String} users.name User name + * @apiSuccess {String} users.username User username + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "user": { + * "_id": "56bd1da600a526986cf65c80" + * "name": "John Doe" + * "username": "johndoe" + * } + * } + * + * @apiError UnprocessableEntity Missing required parameters + * + * @apiErrorExample {json} Error-Response: + * HTTP/1.1 422 Unprocessable Entity + * { + * "status": 422, + * "error": "Unprocessable Entity" + * } + */ router.post('/', async (ctx) => { const user = new User(ctx.request.body.user) From 2f0c87ce91fe44912fc8637d1a1e66b276cc7509 Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 23:42:51 -0500 Subject: [PATCH 14/18] Set error name to `Unauthorized-Error` --- src/controllers/auth.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/auth.js b/src/controllers/auth.js index 5616701..bfef202 100644 --- a/src/controllers/auth.js +++ b/src/controllers/auth.js @@ -9,7 +9,7 @@ const router = new Router({ prefix: '/auth' }) * @apiDefine TokenError * @apiError Unauthorized Invalid JWT token * - * @apiErrorExample {json} Error-Response: + * @apiErrorExample {json} Unauthorized-Error: * HTTP/1.1 401 Unauthorized * { * "status": 401, From ac7b8172ba18360bb661ff4369623d6a09336a60 Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 23:43:03 -0500 Subject: [PATCH 15/18] Add docs for `PUT /users/:id` --- src/controllers/users.js | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/controllers/users.js b/src/controllers/users.js index 5467636..1fa5fb7 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -148,6 +148,46 @@ router.post('/', } ) +/** + * @api {put} /users/:id Update a user + * @apiPermission + * @apiVersion 1.0.0 + * @apiName UpdateUser + * @apiGroup Users + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X PUT -d '{ "user": { "name": "Cool new Name" } }' localhost:5000/users/56bd1da600a526986cf65c80 + * + * @apiParam {Object} user User object (required) + * @apiParam {String} user.name Name. + * @apiParam {String} user.username Username. + * + * @apiSuccess {Object} users User object + * @apiSuccess {ObjectId} users._id User id + * @apiSuccess {String} users.name Updated name + * @apiSuccess {String} users.username Updated username + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "user": { + * "_id": "56bd1da600a526986cf65c80" + * "name": "Cool new name" + * "username": "johndoe" + * } + * } + * + * @apiError UnprocessableEntity Missing required parameters + * + * @apiErrorExample {json} Error-Response: + * HTTP/1.1 422 Unprocessable Entity + * { + * "status": 422, + * "error": "Unprocessable Entity" + * } + * + * @apiUse TokenError + */ router.put('/:id', ensureUser, async (ctx) => { From e96606acdb6a8d81d29955a765845e26a16a3b92 Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 23:46:25 -0500 Subject: [PATCH 16/18] Add docs for `DELETE /users/:id` --- src/controllers/users.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/controllers/users.js b/src/controllers/users.js index 1fa5fb7..70739e3 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -213,6 +213,26 @@ router.put('/:id', } ) +/** + * @api {delete} /users/:id Delete a user + * @apiPermission + * @apiVersion 1.0.0 + * @apiName DeleteUser + * @apiGroup Users + * + * @apiExample Example usage: + * curl -H "Content-Type: application/json" -X DELETE localhost:5000/users/56bd1da600a526986cf65c80 + * + * @apiSuccess {StatusCode} 200 + * + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "status": 200 + * } + * + * @apiUse TokenError + */ router.delete('/:id', ensureUser, async (ctx) => { From 67455677d72d9bc744eb7ae0ff2d14128f1a1bcb Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Fri, 4 Mar 2016 23:58:22 -0500 Subject: [PATCH 17/18] Update readme --- README.md | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 105ad72..fd19ac5 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ Boilerplate for building APIs with [koa2](https://github.com/koajs/koa/tree/v2.x) and mongodb. This project covers basic necessities of most APIs. - * Authentication (passport & jwt) * Database (mongoose) * Testing (mocha) +* Doc generation with jsondoc ##Requirements * node __^4.0.0__ @@ -17,7 +17,7 @@ git clone https://github.com/adrianObel/koa2-api-boilerplate.git ``` ##Features -* [Koa](https://github.com/koajs/koa/tree/v2.x) +* [koa2](https://github.com/koajs/koa/tree/v2.x) * [koa-router](https://github.com/alexmingoia/koa-router) * [koa-bodyparser](https://github.com/koajs/bodyparser) * [koa-generic-session](https://github.com/koajs/generic-session) @@ -27,14 +27,21 @@ git clone https://github.com/adrianObel/koa2-api-boilerplate.git * [Passport](http://passportjs.org/) * [Nodemon](http://nodemon.io/) * [Mocha](https://mochajs.org/) +* [jsondoc](http://apidocjs.com/) * [Babel](https://github.com/babel/babel) -* [ESLint](https://esling.ord) +* [ESLint](http://eslint.org/) ##Structure ``` +├── bin +│ └── server.js # Bootstrapping and entry point ├── config # Server configuration settings -│ ├── server.js # Bootstrapping and entry point -│ ├── config.js # JSON dictionary for environment specific config +│ ├── env # Environment specific config +│ │ ├── common.js +│ │ ├── development.js +│ │ ├── production.js +│ │ └── test.js +│ ├── index.js # Config entrypoint - exports config according to envionrment and commons │ └── passport.js # Passportjs config of strategies ├── src # Source code │ ├── controllers # Routes @@ -47,7 +54,13 @@ git clone https://github.com/adrianObel/koa2-api-boilerplate.git ##Usage * `npm start` Start server on live mode * `npm run dev` Start server on dev mode with nodemon +* `npm run docs` Generate API documentation * `npm test` Run mocha tests +##Documentation +API documentation is written inline and generated by [jsondoc](http://apidocjs.com/). + +Visit `http://localhost:5000/docs/` to view docs + ##License MIT From 8e97911d4edf8974ca691f987f2f777b4f686c75 Mon Sep 17 00:00:00 2001 From: Adrian Obelmejias Date: Sat, 5 Mar 2016 00:05:09 -0500 Subject: [PATCH 18/18] Update lint to ignore comments --- .eslintrc.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index 5f770c4..8af25b1 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,7 +8,8 @@ "semi": [2, "never"], "no-param-reassign": [2, { "props": false }], "strict": 0, - "comma-dangle": [2, "never"] + "comma-dangle": [2, "never"], + "max-len": [2, 80, 2, { "ignoreComments": true }] }, "env": { "node": true,