You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Roxie Gibson 4c85df345f
Added a comment to the edit endpoint, finshing all todos
3 years ago
src Added a comment to the edit endpoint, finshing all todos 3 years ago
.gitignore Initial commit (after many hours work :eyes:) 3 years ago
README.md Initial commit (after many hours work :eyes:) 3 years ago
package-lock.json Moved middleware and helpers to new file. Added basic logging to server 3 years ago
package.json Moved middleware and helpers to new file. Added basic logging to server 3 years ago
products.json Initial commit (after many hours work :eyes:) 3 years ago
tsconfig.json Initial commit (after many hours work :eyes:) 3 years ago
tslint.json Moved helper methods outside of Product and into generic Base class 3 years ago

README.md

Product REST API

A REST API designed for a backend code test for Mission Labs. The background in this fake world is a Mission Labs merch store with a product database for the web store. API has all 4 CRUD methods for its products. Authentication protects any write methods with the X-Token header. All methods below are documents and the code base has comments and documentation throughout.

Setup

Requires node.js 14+, npm, and mongodb

Installation

npm install

MongoDb setup

Make sure you have properly setup a MongoDB instance and its running on the default port. Then run these two commands to insert our test data and set a field as an index.

mongoimport -d ml-test -c products --jsonArray products.json
mongo localhost/ml-test --eval "db.products.createIndex( { identifier: 1 }, { unique: true } )"

Usage

To run the server:

npm run prod

You should see this output

> ml-crud_api@1.0.0 prod /home/roxie/Projects/ts/mission-labs/code-test
> tsc && node ./dist/index.js

API running @ http://127.0.0.1:8081

Great! You are now running the REST API server. It is accessible at http://127.0.0.1:8081. For this demo, the secret key token for authentication is SECRET_KEY.

API Docs

The product schema will be as follows…

{
    "identifier": "url-safe-identifier", // REQUIRED - CAN NOT be empty, needs to be url-safe and lowercase
    "name": "Example Product", // REQUIRED - CAN NOT be empty
    "price": 9000, // REQUIRED - Price is in pence, CAN NOT be negative
    "category": "Examples", // REQUIRED - CAN NOT be empty
    "sizes": ["Example Sized"] // OPTIONAL - Can be empty
}

Searching is done with identifiers instead of ObjectID ID’s to make API more human-readable and accessible.

Items in curly braces are parameters.

List all products

GET /api/products

This endpoint accepts two parameters to filter the output:

  • priceFrom: Define a minimum price of all products in the search
  • priceTo: Define a maximum price of all products in the search

All prices are listed as pence for ease of use.

Responses

  • 200 OK on success
[
    {
        "identifier": "url-safe-identifier",
        "name": "Example Product",
        "price": 9000, // Price is in pence
        "category": "Examples",
        "sizes": ["Example Sized"]
    }
]

Get one product

GET /api/products/{IDENTIFIER}

Responses

  • 200 OK on success.
  • 404 Not Found if product with identifier doesn’t exist.
{
    "identifier": "url-safe-identifier",
    "name": "Example Product",
    "price": 9000, // Price is in pence
    "category": "Examples",
    "sizes": ["Example Sized"]
}

Create new product

POST /api/products/

Responses

  • 200 OK on success/
  • 400 Bad Request when trying to create an object with the same identifier as an existing object.
  • 401 Unauthorized on request without header X-Token being set to an authorized key.

Posted data should be a raw body with the header Content-Type set to application/json. Example of the posted JSON would look like this

{
    "identifier": "ml-cool-logo-cup",
    "name": "Brand New Mugs",
    "price": 500, // Price is in pence
    "category": "Liquid Holders"
}

Update product

PATCH /api/products/{IDENTIFIER}

Edits part of a product object (or all) with the data received.

Responses

  • 200 OK on success.
  • 400 Bad Request if unable to parse some or all of the data received for updating.
  • 401 Unauthorized on request without header X-Token being set to an authorized key.
  • 404 Not Found if product with identifier doesn’t exist.

Posted data should be a raw body with the header Content-Type set to application/json. identifier must be an identifier to an already existing product or else response will be 404 Not Found. Partial updates are allowed when using PATCH. Example of the posted JSON would look like this

// /api/products/mug_1

{
    "name": "Mugs One!",

}

This would change the name of the item.

Delete product

DELETE /api/products/{IDENTIFIER}

Responses

  • 204 No Content on delete success.
  • 401 Unauthorized on request without header X-Token being set to an authorized key.
  • 404 Not Found if product with identifier doesn’t exist.