No description, website, or topics provided.
Switch branches/tags
Nothing to show
Clone or download
Latest commit 3ebde58 Feb 1, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
README.md Update README.md Feb 1, 2019
postman-get.png added pics Jul 26, 2018
postman-post.png added pics Jul 26, 2018

README.md

express-fruits-api

Objectives

  1. Review Rest
  2. Describe API
  3. Using Postman to test API's

JSON API's should be RESTful.

REST is well agreed upon as the best practice for the architecture of backend applications.

Remember:

GET ALL VIDEOS "/videos"

GET VIDEO BY ID "/vidoes/:id"

POST CREATE VIDEO "/videos"

PUT UPDATE VIDEO: "/videos/:id"

DELETE VIDEO: "/videos/:id"

What is a JSON API?

Last unit we focused on building Full Stack Express Applications using EJS, but now we will be moving on to API's.

In simple terms, that's what a JSON API is. It is a backend application with no views, it just accepts and serves JSON. In some cases, it simply serves as a interface for a database, and only implements simple CRUD actions.

JSON API best practices Review

  1. scope your api in an 'api' namespace.
  2. version your api
https://www.comedyvideos.com/api/v2/videos

Decoupled Applications

A decoupled application is where the front end treats its own back end like an external API, rather than the backend serving up the front end application.

Many of you made use of JSON for your full stack Express app by using AJAX. That's awesome! You could do the same thing with a React front end. Essentiall, you just serve up that initial index.html page that contains that <div id="root"></div> from within your Express App, and put all of your React files in the Public folder.

This can be great, but decoupled apps have some advantages.

  1. If you ever want to change back end technologies, like move from Express to Django, or vice versa, the ONLY thing you need to change on your front end are the API endpoints in your AJAX calls.

  2. If you ever want to change front end technologies, like go from React to Vue, or vice versa, you litterally don't need to touch your back end at all.

  3. You have two smaller repos with less code. Have a React dev that knows nothing about Express? Great! They don't have to. Have an Express dev who knows nothing about React? Great! They don't have to. They work on completely seperate code bases!

Drawbacks:

There's only one: you have to set up CORS, or cross origin resource sharing. But don't worry, that's easy!

CORS in Express

npm install cors

const express = require('express');
const cors = require('cors');
const app = express();

app.use(cors());

It's as simple as that to get started. This will allow requests to any route from ANY origin, so in the future, you will want to configure CORS to ONLY take requests from your front end app, unless you want it open to the public.

Check out the node modules github for details on how to configure CORS more.

Clone the following repo and implement the proper responses

Our final code should look like the following,

  • FruitController.js
const express = require('express');
// Next we set up the Router
const router = express.Router();
// require Our Model - Remember Model is
// a representation of our data
// The model should capitalized
const Fruits = require('../models/fruits');
// Creating the index route
// index route should show all the fruits
router.get('/', (req, res) => {
  // finding every fruit without a search parameter
  Fruits.find({}, (err, allFruits) => {
    if(err){
      res.send(err);
    } else {
        res.json({status: 200,
                 data: allFruits
               });
    };
  });



});

// This is the route that the form is sending
// its info too
// aka the create route
router.post('/', (req, res) => {
  // contents of the form will be in req.body

  console.log(req.body, 'this is req.body, should be form info');
  if(req.body.readyToEat === 'on'){
    req.body.readyToEat = true;
  } else {
    req.body.readyToEat = false;
  }
  // adding the contents of the form to the model
  Fruits.create(req.body, (err, createdFruit)=> {
    if(err){
      console.log(err)
      res.send(err);
    } else {
      console.log(createdFruit)
      // we want to respond to the client after
      // we get the response from the database
      // redirects the response back
      // to the get /fruits route
      res.json({status: 201, data: createdFruit});
    }
  });
});




// Show Route
router.get('/:id', (req, res) => {

  // Render is when you want to send
  // an ejs template to the client
  Fruits.findById(req.params.id, (err, foundFruit) => {
      res.json({
      status: 200,
      data: foundFruit
    });
  });

});

router.put('/:id', (req, res) => {
  console.log(' am I hitting the put route') // Check to see if im hitting im route
  // If Im not hitting the route, there is probably something with the action of form

  // If it is hitting the route, I want to see
  console.log(req.body, 'Why: IT tells what is coming from the form')

  if(req.body.readyToEat === 'on'){ // if checked then req.body.readyToEat = 'on'
    req.body.readyToEat = true;
  } else {
    req.body.readyToEat = false;
  }
  // req.body is the updated form info
  //new true, says return to me the updated object, by default it is false
  // things that are default you don't have to specify

  // first argument, is the document you are looking for
  // second argument, is the content you are updating with
  Fruits.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, updatedFruit) => {
    if(err){
      res.send(err);
    } else {
        res.json({status: 200, data: updatedFruit})
    }
  })

});


// Delete route
router.delete('/:id', (req, res) => {

  // Delete a specific fruit
  console.log(req.params.id, ' this is params in delete')
  Fruits.findByIdAndRemove(req.params.id, (err, deletedFruit) => {
    if(err){
      console.log(err, ' this is error in delete')
      res(err);
    } else {
      console.log(deletedFruit, ' this deletedfruit in the delete rout');
      res.json({status: 200, data: deletedFruit});
    }
  });



})
module.exports = router;
  • And the Server File, noticed how we renamed our Route for our controller.
const express        = require('express');
const app            = express();
const bodyParser     = require('body-parser');
const methodOverride = require('method-override');
const cors           = require('cors');


require('./db/db');


// SET UP CORS AS MIDDLEWARE, SO any client can make a request to our server
app.use(cors());
app.use(bodyParser.urlencoded({extended: false}))
app.use(methodOverride('_method'));

// Require the controller after the middleware
const fruitController = require('./controllers/fruitController');


app.use('/api/v1/fruits', fruitController);


app.listen(3000, () => {
  console.log('listening on port 3000');
});

Postman

  • Postman is a tool for us to simulate HTTP requests, so we can just work on our backend without needing a frontend to make API calls, you should have installed postman at the beginning of class so just search your computer to find postman otherwise download the app.

  • Here's an example of a get request

Get

  • Here's an example of a post request
  • Note inside of the body tag we are selecting 'x-www-form-urlencoded' in order to simulate a form request, then we can add the key and value pairs, and then hit submit

Post