Skip to content

Instantly share code, notes, and snippets.

@scriptmaster
Forked from JedWatson/KeystoneApiExample.md
Last active November 7, 2017 23:01
Show Gist options
  • Select an option

  • Save scriptmaster/561c7aa1e4e99ff0be0fac82ea8571e4 to your computer and use it in GitHub Desktop.

Select an option

Save scriptmaster/561c7aa1e4e99ff0be0fac82ea8571e4 to your computer and use it in GitHub Desktop.

Revisions

  1. scriptmaster revised this gist Nov 7, 2017. 1 changed file with 15 additions and 15 deletions.
    30 changes: 15 additions & 15 deletions routes-api-posts.js
    Original file line number Diff line number Diff line change
    @@ -9,9 +9,9 @@ var Post = keystone.list('Post');
    exports.list = function(req, res) {
    Post.model.find(function(err, items) {

    if (err) return res.apiError('database error', err);
    if (err) return res.status(500).json('database error', err);

    res.apiResponse({
    res.json({
    posts: items
    });

    @@ -24,10 +24,10 @@ exports.list = function(req, res) {
    exports.get = function(req, res) {
    Post.model.findById(req.params.id).exec(function(err, item) {

    if (err) return res.apiError('database error', err);
    if (!item) return res.apiError('not found');
    if (err) return res.status(500).json('database error', err);
    if (!item) return res.status(404).json('not found');

    res.apiResponse({
    res.json({
    post: item
    });

    @@ -45,9 +45,9 @@ exports.create = function(req, res) {

    item.getUpdateHandler(req).process(data, function(err) {

    if (err) return res.apiError('error', err);
    if (err) return res.status(500).json('error', err);

    res.apiResponse({
    res.json({
    post: item
    });

    @@ -60,16 +60,16 @@ exports.create = function(req, res) {
    exports.update = function(req, res) {
    Post.model.findById(req.params.id).exec(function(err, item) {

    if (err) return res.apiError('database error', err);
    if (!item) return res.apiError('not found');
    if (err) return res.status(500).json('database error', err);
    if (!item) return res.status(404).json('not found');

    var data = (req.method == 'POST') ? req.body : req.query;

    item.getUpdateHandler(req).process(data, function(err) {

    if (err) return res.apiError('create error', err);
    if (err) return res.status(500).json('create error', err);

    res.apiResponse({
    res.json({
    post: item
    });

    @@ -84,13 +84,13 @@ exports.update = function(req, res) {
    exports.remove = function(req, res) {
    Post.model.findById(req.params.id).exec(function (err, item) {

    if (err) return res.apiError('database error', err);
    if (!item) return res.apiError('not found');
    if (err) return res.status(500).json('database error', err);
    if (!item) return res.status(404).json('not found');

    item.remove(function (err) {
    if (err) return res.apiError('database error', err);
    if (err) return res.status(500).json('database error', err);

    return res.apiResponse({
    return res.json({
    success: true
    });
    });
  2. scriptmaster revised this gist Nov 7, 2017. 1 changed file with 21 additions and 6 deletions.
    27 changes: 21 additions & 6 deletions routes-index.js
    Original file line number Diff line number Diff line change
    @@ -12,6 +12,19 @@ var routes = {
    api: importRoutes('./api')
    };

    function checkAuth(req, res, next) {
    // you could check user permissions here too
    if (req.user) return next();
    return res.status(403).json({ 'error': 'no access' });
    }

    function checkAdmin(req, res, next) {
    // you could check user permissions here too
    if (req.user && req.user.isAdmin) return next();
    return res.status(403).json({ 'error': 'no access' });
    }


    // Setup Route Bindings
    exports = module.exports = function(app) {

    @@ -22,11 +35,13 @@ exports = module.exports = function(app) {
    app.get('/gallery', routes.views.gallery);
    app.all('/contact', routes.views.contact);

    app.all('/api*', keystone.middleware.api);
    app.get('/api/post/list', keystone.middleware.api, routes.api.posts.list);
    app.all('/api/post/create', keystone.middleware.api, routes.api.posts.create);
    app.get('/api/post/:id', keystone.middleware.api, routes.api.posts.get);
    app.all('/api/post/:id/update', keystone.middleware.api, routes.api.posts.update);
    app.get('/api/post/:id/remove', keystone.middleware.api, routes.api.posts.remove);
    // app.all('/api*', keystone.middleware.api); // Only needed if you use res.apiResponse() which you can do with res.json()
    app.get('/api/post/list', routes.api.posts.list);
    app.all('/api/post/create', routes.api.posts.create);
    app.get('/api/post/:id', routes.api.posts.get);
    app.all('/api/post/:id/update', routes.api.posts.update);
    app.get('/api/post/:id/remove', routes.api.posts.remove);

    app.all('/api/user/*', checkAuth);
    app.all('/api/admin/*', checkAdmin);
    }
  3. scriptmaster revised this gist Nov 7, 2017. 1 changed file with 7 additions and 7 deletions.
    14 changes: 7 additions & 7 deletions routes-index.js
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,4 @@
    var _ = require('underscore'),
    keystone = require('keystone'),
    var keystone = require('keystone'),
    middleware = require('./middleware'),
    importRoutes = keystone.importer(__dirname);

    @@ -23,10 +22,11 @@ exports = module.exports = function(app) {
    app.get('/gallery', routes.views.gallery);
    app.all('/contact', routes.views.contact);

    app.get('/api/post/list', keystone.initAPI, routes.api.posts.list);
    app.all('/api/post/create', keystone.initAPI, routes.api.posts.create);
    app.get('/api/post/:id', keystone.initAPI, routes.api.posts.get);
    app.all('/api/post/:id/update', keystone.initAPI, routes.api.posts.update);
    app.get('/api/post/:id/remove', keystone.initAPI, routes.api.posts.remove);
    app.all('/api*', keystone.middleware.api);
    app.get('/api/post/list', keystone.middleware.api, routes.api.posts.list);
    app.all('/api/post/create', keystone.middleware.api, routes.api.posts.create);
    app.get('/api/post/:id', keystone.middleware.api, routes.api.posts.get);
    app.all('/api/post/:id/update', keystone.middleware.api, routes.api.posts.update);
    app.get('/api/post/:id/remove', keystone.middleware.api, routes.api.posts.remove);

    }
  4. @JedWatson JedWatson renamed this gist Mar 24, 2014. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  5. @JedWatson JedWatson created this gist Mar 24, 2014.
    22 changes: 22 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,22 @@
    This is an example of how to scaffold API endpoints to list / get / create / update / delete Posts in a Keystone website.

    It's a modification of the default project created with the `yo keystone` generator (see https://github.com/JedWatson/generator-keystone)

    Gists don't let you specify full paths, so in the project structure the files would be:

    ````
    routes-index.js --> /routes/index.js // modified to add the api endpoints
    routes-api-posts.js --> /routes/api/posts.js // new file containing the Post API route controllers
    ````

    It creates JSON endpoints for:

    * `/api/post/list` - lists all posts
    * `/api/post/create` - creates a new post
    * `/api/post/{id}` - returns the details of posts by id
    * `/api/post/{id}/update` - updates a post by id and returns the details
    * `/api/post/{id}/delete` - deletes a post by id

    The `create` and `update` routes accept either GET or POST requests for simplicity, and look in either the URL parameters of the request body for data using the same paths as set on the models.

    You can add your own logic in for security, default values, limiting fields etc. by configuring the functions exported by `/routes/api/posts.js`
    99 changes: 99 additions & 0 deletions routes-api-posts.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,99 @@
    var async = require('async'),
    keystone = require('keystone');

    var Post = keystone.list('Post');

    /**
    * List Posts
    */
    exports.list = function(req, res) {
    Post.model.find(function(err, items) {

    if (err) return res.apiError('database error', err);

    res.apiResponse({
    posts: items
    });

    });
    }

    /**
    * Get Post by ID
    */
    exports.get = function(req, res) {
    Post.model.findById(req.params.id).exec(function(err, item) {

    if (err) return res.apiError('database error', err);
    if (!item) return res.apiError('not found');

    res.apiResponse({
    post: item
    });

    });
    }


    /**
    * Create a Post
    */
    exports.create = function(req, res) {

    var item = new Post.model(),
    data = (req.method == 'POST') ? req.body : req.query;

    item.getUpdateHandler(req).process(data, function(err) {

    if (err) return res.apiError('error', err);

    res.apiResponse({
    post: item
    });

    });
    }

    /**
    * Get Post by ID
    */
    exports.update = function(req, res) {
    Post.model.findById(req.params.id).exec(function(err, item) {

    if (err) return res.apiError('database error', err);
    if (!item) return res.apiError('not found');

    var data = (req.method == 'POST') ? req.body : req.query;

    item.getUpdateHandler(req).process(data, function(err) {

    if (err) return res.apiError('create error', err);

    res.apiResponse({
    post: item
    });

    });

    });
    }

    /**
    * Delete Post by ID
    */
    exports.remove = function(req, res) {
    Post.model.findById(req.params.id).exec(function (err, item) {

    if (err) return res.apiError('database error', err);
    if (!item) return res.apiError('not found');

    item.remove(function (err) {
    if (err) return res.apiError('database error', err);

    return res.apiResponse({
    success: true
    });
    });

    });
    }
    32 changes: 32 additions & 0 deletions routes-index.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,32 @@
    var _ = require('underscore'),
    keystone = require('keystone'),
    middleware = require('./middleware'),
    importRoutes = keystone.importer(__dirname);

    // Common Middleware
    keystone.pre('routes', middleware.initLocals);
    keystone.pre('render', middleware.flashMessages);

    // Import Route Controllers
    var routes = {
    views: importRoutes('./views'),
    api: importRoutes('./api')
    };

    // Setup Route Bindings
    exports = module.exports = function(app) {

    // Views
    app.get('/', routes.views.index);
    app.get('/blog/:category?', routes.views.blog);
    app.get('/blog/post/:post', routes.views.post);
    app.get('/gallery', routes.views.gallery);
    app.all('/contact', routes.views.contact);

    app.get('/api/post/list', keystone.initAPI, routes.api.posts.list);
    app.all('/api/post/create', keystone.initAPI, routes.api.posts.create);
    app.get('/api/post/:id', keystone.initAPI, routes.api.posts.get);
    app.all('/api/post/:id/update', keystone.initAPI, routes.api.posts.update);
    app.get('/api/post/:id/remove', keystone.initAPI, routes.api.posts.remove);

    }