/pizzeria

Primary LanguageTypeScript

Monorepo structure

This is a lerna project with two main packages called pizzeria-backend and pizzeria-frontend. Everything is written in TypeScript, and Webpack is used in each package individually.

How to run in development

First, at the root of the project, run npm run bootstrap, which simply npm installs everything (uses lerna to manage the dependencies).

pizzeria-backend

npm run start:backend

What this does is run two other npm scripts sequentially: one to run webpack in watch mode, and the other to run the node api server using nodemon.

For some reason running the backend like this does not show debugging info in the console. To see such information, run the two scripts in two separate terminals: npm run start:backend:webpack-watch and npm run start:backend:server.

You can now test the endpoints.

pizzeria-frontend

npm run start:frontend

This just runs react-scripts start; this is the standard create-react-app way of running the app in development. You can navigate to localhost:3000 and interact with the backend through there.

Features

  • sign up or sign in to an existing account
  • add menu items to your cart
  • checkout and make payment (integration with Stripe payments API is fully on the backend, the frontend just hits an endpoint to process the order)
  • backend sends email on successful order
  • see all orders on the frontend

Endpoints

There is a Router class that I wrote to allow adding routes. I added this so I could add more complex routes, by using regular expressions to match the URI path.

The routes themselves are defined in apps/pizzeria-backend/src/index.ts.

GET /tokens

  • payload: { id: string }

POST /tokens

  • payload: { username: string, password: string }

PUT /tokens

  • payload: { id: string, extend: boolean }

DELETE /tokens

  • payload: { id: string }

GET /users

  • queryString: { username: string }
  • headers: { token: string }

POST /users

  • payload: { username: string, password: string, email: string, address: string }

PUT /users

  • payload: { username: string, password?: string, email?: string, address?: string }
  • headers: { token: string }

DELETE /users

  • queryString: { username: string }
  • headers: { token: string }

GET /users/:username/cart

  • headers: { id: string }

PUT /users/:username/cart

  • headers: { id: string },
  • payload: { cart: { [productId: string]: number } }
  • adds products in passed in cart to the user cart

DELETE /users/:username/cart

  • headers: { id: string },
  • payload: { cart: { [productId: string]: number } }
  • removes products in passed in cart from the user cart

GET /users/:username/orders

  • headers: { id: string }

POST /users/:username/checkout

  • headers: { id: string }

The use of TypeScript documents the types of inputs and outputs of the handlers.

Note

  • Regarding Mailgun integration, since I am using the sandbox, the final email can only be sent to specific email accounts added through the Mailgun web interface.