Skip to content

RESTful API for managing a store - CRUD of products and sales.

Notifications You must be signed in to change notification settings

PedroPA94/store-manager--trybe

Repository files navigation

Welcome!

This project is a Back-end RESTful API for managing a store. It enables the creation, listing, updating and deletion (CRUD) of products and sales. I also wrote tests for the API.

In this project I was able to apply the concepts of software architecture based on layers. Three layers are used: Model, Service and Controller (MSC). The Model is responsible for communicating with the database, the middle layer, Service, validates the business rules and the Controller receives and responds HTTP requests.

This project was developed while studying Back-end web development @betrybe. The files I worked on are in the /src and /tests folders. I got approval on 100% of this project's requirements.

Below is the database diagram: EER Diagram

Main languages and tools used

  • Node.js
  • Express.js
  • MySQL
  • Joi for input data validation
  • Tests with Mocha, Chai and Sinon
  • Docker
  • Layered Software Architecture

Installation

With Docker
  • Start the store_manager and store_manager_db containers with the docker-compose up -d command
  • Access the store_manager container terminal with docker exec -it store_manager bash
  • In the terminal, install the dependencies with npm install
  • All other node commands must be run inside the container
Without Docker
  • Install the dependencies with npm install (requires node on version 16)
  • Configure a .env file based on the .env.example avaliable.
Commands
  • Run the app with npm start or npm run debug (live reload)
  • Use npm run migration to create the database and entities and npm run seed to populate it
  • To run the project's requirements tests, first start the app with npm run dev, then npm test for all tests or npm test <test-name> for a specific requirement (ex. npm test req01)
  • User npm run test:mocha to run the tests done by me

Endpoints

GET /products
  • Returns an array with all the registered products ordered by their id, or an empty array if there are no products.

  • Example:
[
  {
    "id": 1,
    "name": "Martelo de Thor"
  },
  {
    "id": 2,
    "name": "Traje de encolhimento"
  }
]
GET /products/:id
  • Returns the product with the specified id. If there are no matches, returns status 404 with a message.

  • Example of match:
{
  "id": 1,
  "name": "Martelo de Thor"
}
  • Example of no match:
{ "message": "Product not found" }
POST /products
  • Creates a new product in the products table and returns it with the inserted id. Two validations are done: (1) the product needs a name and (2) the name must be at least 5 characters long. If the new entry fails any of the validations, a message is returned instead.

  • Example request body:
{
  "name": "ProdutoX"
}
  • Example of response for valid entry:
{
  "id": 4,
  "name": "ProdutoX"
}
  • Response for request without a "name" field (status 400):
{ "message": "\"name\" is required" }
  • Response for request with an invalid "name" (status 422):
{ "message": "\"name\" length must be at least 5 characters long" }
PUT /products/:id
  • Updates a product and returns it with the respective id. The same validations of the product creation are done.

  • Example request body:
{
  "name": "Martelo do Batman"
}
  • Example of return:
{
  "id": 1,
  "name": "Martelo do Batman"
}
  • Invalid id (status 404):
  { "message": "Product not found" }
DELETE /products/:id
  • Deletes a product and returns status 204. Validates if product exists.
GET /products/search?q=searchTerm
  • Returns an array of products whose names matches the request search term. If there are no matches, returns an empty array. If the search term is empty, returns an array with all registered products.

  • Example of match:
/products/search?q=Martelo
[
  {
    "id": 1,
    "name": "Martelo de Thor"
  }
]
GET /sales
  • Returns an array with all the registered sales ordered by their saleId and productId, or an empty array if there are no sales.

  • Example:
[
  {
    "saleId": 1,
    "date": "2021-09-09T04:54:29.000Z",
    "productId": 1,
    "quantity": 2
  },
  {
    "saleId": 1,
    "date": "2021-09-09T04:54:54.000Z",
    "productId": 2,
    "quantity": 2
  }
]
GET /sales/:id
  • Returns the sale with the specified id, ordered by the productId. If there are no matches, returns status 404 with a message.

  • Example of match:
[
  {
    "date": "2021-09-09T04:54:29.000Z",
    "productId": 1,
    "quantity": 2
  },
  {
    "date": "2021-09-09T04:54:54.000Z",
    "productId": 2,
    "quantity": 2
  }
]
  • Example of no match:
{ "message": "Sale not found" }
POST /sales
  • Inserts a new sale in the sales and sales_products tables. The sale can be of one or many products. Four validations are done: (1) the "productdId" field is required; (2) the "quantity" field is required; (3) the "quantity" is greater than zero; (4) the "productId" corresponds to a registered product in the database.

  • Example request body:
[
  {
    "productId": 1,
    "quantity": 1
  },
  {
    "productId": 2,
    "quantity": 5
  }
]
  • Example of response for valid entry:
{
  "id": 3,
  "itemsSold": [
    {
      "productId": 1,
      "quantity": 1
    },
    {
      "productId": 2,
      "quantity": 5
    }
  ]
}
  • Response for request without a "productId" field (status 400):
{ "message": "\"productId\" is required" }
  • Response for request without a "quantity" field (status 400):
{ "message": "\"quantity\" is required" }
  • Response for request with an invalid "productId" (status 404):
{ "message": "Product not found" }
  • Response for request with an invalid "quantity" (status 422):
{ "message": "\"quantity\" must be greater than or equal to 1" }
PUT /sales/:id
  • Updates a sale and returns it with the respective id. The same validations of the sale creation are done.

  • Example request body:
[
  {
    "productId": 1,
    "quantity": 10
  },
  {
    "productId": 2,
    "quantity": 50
  }
]
  • Example of return:
  "saleId": 1,
    "itemsUpdated": [
      {
        "productId": 1,
        "quantity":10
      },
      {
        "productId": 2,
        "quantity":50
      }
    ]
  • Invalid id (status 404):
  { "message": "Sale not found" }
DELETE /sales/:id
  • Deletes a sale and returns status 204. Validates if sale exists.