Skip to content

Instantly share code, notes, and snippets.

@formula1
Created February 7, 2017 19:28
Show Gist options
  • Save formula1/2e71d0b81a33fe569976975f73995c61 to your computer and use it in GitHub Desktop.
Save formula1/2e71d0b81a33fe569976975f73995c61 to your computer and use it in GitHub Desktop.
Lesson CRUD

Purpose

Teach Developer how to implement simple reusable components and leaving complex database interdependency and logic to those database models.

Why is it good

There will be bugs in your code, there always is. However, there are many benefits to DRY principles.

  • Not reimplementing logic
  • Not rewriting everything
  • Not cutting and pasting
  • If a bug is found in your router code, it can be handled everywhere

Additionally, growth as a programmer has less to do with speed of typing and more to do how well you recognize, organize and solve the problem at hand. Abstraction is how we have things like react and express.

What it teaches

  • Router
  • use, middleware (bodyparser)
  • get, post, delete
  • mix and match promises with callbacks
  • delegating errors to final callback
  • status codes

Perfect-ish Solution

I want them to be able to implement it themselves at first.

// crud-router.js
var qs = require("qs");
var bodyParser = require("body-parser");
module.exports = function(model) {
  var renderSuccess = function(res, value){
    res.send({
      type: "success",
      result: value
    });
  };
  var renderFailure = function(res, status, error){
    res.status(status)
    res.send({
      type: "error",
      result: error
    });
  };
  var router = new express.Router();
  router.get("/", function(req, res, next){
    model.search(qs.parse(req.query)).then(function(list){
      renderSuccess(res, list)
    });
  });
  router.post("/", bodyParser(), function(req, res, next){
    model.create(req.body).then(function(instance){
      renderSuccess(res, instance);
    }, next);
  });
  router.get("/:id", function(req, res, next){
    model.findById(req.params.id).then(function(instance){
      if(!instance) return renderFailure(res, 404, "instance not found");
      renderSuccess(res, instance);
    }, next);
  });
  router.post("/:id", bodyParser(), function(req, res, next){
    model.findByIdAndUpdate(req.params.id, req.body).then(function(instance){
      renderSuccess(res, instance);
    }, function(err){
      if(err === "Not Found"){
        return renderFailure(res, 404, "instance not found");
      }
      next(err);
    });
  });
  router.delete("/:id", function(req, res, next){
    model.findByIdAndDelete(req.params.id).then(function(instance){
      if(!instance) return renderFailure(res, 404, "instance not found");
      renderSuccess(res, instance);
    }, next);
  });
  router.use(function(error, req, res, next) {
    renderFailure(res, 500, error.message || error.toString());
  });
}
// express app
var express = require("express");
var crudRouter = require("./crud-router");
var models = require("./models"); // Will export a large list of models
var app = express();
models.forEach(function(model){
  app.use(model.name, crudRouter(model));
})
app.listen(8080);

Follow Up Lessons

  • Sanitize the Input
  • Use GraphQL - making life easier
  • Use MySql - realistic for job
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment