Pt4 Building a food order system with MEAN Stack (MongoDB, Express, AngularJs and NodeJs).

in #utopian-io6 years ago (edited)

In our Last tutorial , we created the item model, controller and routes. The various End-point for every item on the controller was created.

Overview.

Now we have our user model ready, in this installment, we are going to add some new methods and function for our orders. We are going to create our Order model Route and some controller method. then secure some routes with passport as a middleware.
Finally we are going to use postman to test..

Requirement.

  • Typescript version 2.4.2
  • Node version version 8.9.4
  • Npm version 5.6.0
  • Express version ^4.15.3.
  • Postman
  • Voltron Server Repository

Table of content.

  1. Creating the order model.
  2. Creating the order router and its End-point
  3. Creating the order Controller and its methods
  4. Securing Routes with passport jwt.
  5. Testing with Postman.

Difficulty

This tutorial is rated intermediate.

Creating the Order Model.

In our previous series, we explain the concept of embedding in mongodb. here is the implementation below.

Untitled-1.jpg

Schematic Diagram showing the user Object embedded in the order model

As show above, a user object is created along side the item, which makes up the order. This is done to increase the efficiency of the query carried out from the Front-end to the server side. In this case, each time we make a request for a particular order, the user is passed along as a responses from the server. Embedding is simply passing along part or any item that would be required as a dependency in another model.

import { Schema, model, Document } from 'mongoose';

let OrderSchema: Schema = new Schema({
    user: {
        type: Object,
        required: true,
      },
    items: {
        type: Array,
        required: true,
        default: []
    },
    createdAt: {
      type: Date,
      default: new Date
    },
    updatedAt: {
      type: Date,
      default: new Date
    },
    deletedAt: {
        type: Date,
    }, 
});

interface OrderSchemaDoc extends Document {}

export default model<OrderSchemaDoc>('Order', OrderSchema);

Just as explained with the schematic diagram, there is a user which has a type of Object, the user object is set to required on this model. The items has a type of array which we are going to populate with many item.

Note: The items contain item of various quantity, description, price etc.

Untitled-2.jpg

Schematic diagram showing the Array of items and a user object passed along

we create the createdAt updatedAt and deletedAt to know when the create, update and delete function were carried out. The field on the model has a type of Date.

Creating the order router and its End-point.

In the config/routes.ts we are going to add a new End-point prefix and pass the route file we want to use. Our Route file would be order.router.ts which we would create in api/order/order.router.ts

this.app.use('/api/orders', OrderRouter);

Dont forget to add the line of code below to import our OrderRouter
import OrderRouter from '../api/order/order.router';

Add the above to the setAllRoutes method, this create a prefix called localhost:3000/api/orders

Creating the order.router.ts
In creating this file, we have to import a controller and Router from express, the controller would be called the OrderController, this is where all the logic for our End-points would be carried out.

import { Router, Request, Response, NextFunction } from 'express';
import OrderController from './order.controller';

Next up lets add the route End-points which have different protocols. as discussed in the previous series

init () {
        this.router.put('/:_id', OrderController.updateOrder);
        this.router.get('/', OrderController.getAll);
        this.router.get('/:_id', OrderController.getOrder);
        this.router.post('/', OrderController.createOrder);
        this.router.delete('/:_id', OrderController.deleteOrder);
    }

In the init method, add the following End-points for different Actions using different protocols
PUT to update
POST to create a new data.
GET to recieve data from the db.

For the purpose of this tutorial, we would be creating just two of the end points.
namely;

  • The endpoint to create an order.
  • The endpoint to get a single order

Before working on the endpoints, we need to create our orderController in api/order/order.controller.ts

Now we have our controller, lets work on the endpoints.
In the controller, at the top import the following modules, Request, Response, NextFunction from express, the user model and the order model.

import { Request, Response, NextFunction } from 'express';
import OrderModel from './order.model';
import UserModel from '../user/user.model';

The endpoint to create an order

To create the order, we have to add the user object and item to the model.

public static async createOrder(req: Request, res: Response, next: NextFunction) {
        
        let { user, items } = req.body;
        
        // Create model
        let orderModel = new OrderModel({
            user,
            items
        });
        // 
        // Save
        await orderModel.save();

        res.send({
            message: `Created order with the id: ${orderModel._id}`,
            model: orderModel
        });
    }

We create an async method called createOrder, we get the request from the body and save to the orders collection, if successful we print out a message.

The endpoint to get a single order.

This endpoint uses a get protocol, and uses the a method on mongoose called findOne() which accepts any parameter from the model. This time we are using the _id of the order to locate the order

public static async getOrder(req: Request, res: Response, next: NextFunction) {

        try {

            // 
            // Get data
            const _id: String = req.params.id;
            let result = await OrderModel.findOne({ _id }).exec();
            const status = res.statusCode;

            // 
            // Response
            res.send({
                message: 'Successfull got an order',
                result: result,
                status: status
            });
        } catch (err) {

            // 
            // Error response
            res.send({
                message: 'Could not the order',
                err: err
            });
        }
    }

All we are doing is simply passing the id to the method to find and return the order from thedb` if none found found, we simply return with a message.

Securing Routes with passport jwt.

In our previous series, we made an introduction to passport jwt and we explained how it works. We would have to protect some routes in the backend, with passport, so that only an authenticated user with a jwt acess token can access the routes.

I Am going to show you an example of a route secured with jwt and how we can access this route using postman.

Note: postman would be assumed to be our front end application.

Protecting the route to get all items
On the item.router.ts import the code below to make passport avialable

import * as passport from 'passport';

on the route, modify the code to use the passport.authenticate method.

this.router.get('/', passport.authenticate('jwt', {session: false}), ItemController.getAll);


We successfully got the route secured with passport, the only way to access that route, you must provide a token generated when you login.

jwt.gif

If you noticed, the route localhost:3000/api/items return unauthorized due to passport securing the route. The only way to access the route is to set the authorization header to the jwt token.

Conclusion

This is the final series for the backend service for voltron, in the next series, we would work more with components, services observables. Intresting stuffs from angular 5. We finally learn how to create models, embbed data, secure routes and make request from the server.

Curriculum

Resources

Sort:  

Hey @sirfreeman

We're already looking forward to your next contribution!

Decentralised Rewards

Share your expertise and knowledge by rating contributions made by others on Utopian.io to help us reward the best contributions together.

Utopian Witness!

Vote for Utopian Witness! We are made of developers, system administrators, entrepreneurs, artists, content creators, thinkers. We embrace every nationality, mindset and belief.

Want to chat? Join us on Discord https://discord.me/utopian-io

You have a minor misspelling in the following sentence:

GET to recieve data from the db.
It should be receive instead of recieve.

I'm not much of a cook - but this looks simple enough to make. Have you tried cooking while sipping on a Vienna lager?

Beautiful post

Please Stop

In your your last 100 comments you used 37 phrases considered to be spam. You've received 4 flags and you may see more on comments like these. These comments are the reason why your Steem Sincerity API classification scores are Spam: 84.00% and Bot: 2.30%

Please stop making comments like this and read the ways to avoid @pleasestop and earn the support of the community.

Thank you for the contribution It has been approved.


Need help? Write a ticket on https://support.utopian.io.
Chat with us on Discord.

[utopian-moderator]

That's a good informative post

Coin Marketplace

STEEM 0.28
TRX 0.11
JST 0.034
BTC 66396.53
ETH 3174.43
USDT 1.00
SBD 4.15