RESTful APIs demo for performing CRUD requests on a Shopping Cart database.
Live preview of this RESTful API can be used on Heroku, see usage for details.
Documentation on the source code can be found here.
The following includes all base dependencies for running the API backend:
12.22.1
1.22
+12
+ recommended)Optionally for using a PostgreSQL container in development:
docker
docker-compose
All project dependencies can be fetch by yarn install
or npm install
. Project dependencies are specified and listed under package.json
.
Some configuration is needed to be set by environment variables.
Here is a list of environments variables to set:
DATABASE_URL
: A URL to the backend PostgreSQL database for use by the APIs, example format: 'postgres://[user]:[password]@[hostname]:[port]/[dbname]
'DATABASE_SSL
(Optional): If set to any value, the API service will use an SSL enabled connection to DATABASE_URL
specified.WEB_CONCURRENCY
: Specifies an integer which indicates the number of web listeners to run at once, if not specified only one listener will run.PGPORT
(For docker-compose
DB only): Specifies the port number to use on PostgreSQL docker
container.PGPASSWORD
(For docker-compose
DB and DB access only): Specifies password to use for the postgres
user in docker
container, also allows for passwordless access to a psql
connection for management.Attributes | Type | Key | Description |
---|---|---|---|
cart_id | INTEGER | PK | Unique identifier for a shopping cart. |
cart_subtotal | NUMERIC | Subtotal cost of all items (without discounts and taxes applied). | |
cart_discount | NUMERIC | Discount percentage to be applied to cart total. | |
cart_taxes | NUMERIC | Total tax cost for entire cart to be applied to total cost. | |
cart_total | NUMERIC | Total cost of items (with discounts and taxes applied). |
Attributes | Type | Key | Description |
---|---|---|---|
item_id | INTEGER | PK | Unique identifier for a shopping cart item. |
cart_id | INTEGER | FK | Unique identifier for a shopping cart that contains item. |
item_label | VARCHAR | Label for identifing item (item name). | |
item_price | NUMERIC | Cost of item (without discounts and taxes applied). |
Attributes | Type | Key | Description |
---|---|---|---|
tax_id | INTEGER | PK | Unique identifier for a tax percentage. |
tax_label | VARCHAR | 3-letter label for tax percentage. | |
tax_percent | NUMERIC | Tax percentage. |
Ensure there is a target PostgreSQL database running with the DATABASE_URL
environment variable set to its url before running API service, even in development.
To run service in development mode (watching for file changes) run the following:
yarn watch
To build production JavaScript for NodeJS deployment run the following:
yarn build
To clean built production source run:
yarn clean
To run production service (in project folder) run:
yarn start
Note: yarn build
must be ran before yarn start
.
At this time, docker
is only used to run a development PostgreSQL database using docker-compose
.
The following will launch a instance of a PostgreSQL container:
export PGPORT=<port_number>
export PGPASSWORD=<password_for_postgres_user>
docker-compose up -d
To stop and remove all launched instances run the following:
docker-compose down
PUT /api/v1/add
: Creates records in database for items and parent cart from JSON repersentation of a cart shown below:With Discount
{
"discount": 0.1, // 10%
"items": [
{
"label": "Milk",
"price": 2.99
},
{
"label": "Cereal",
"price": 3.99
},
...
]
}
Without Discount
{
"items": [
{
"label": "Milk",
"price": 2.99
},
{
"label": "Cereal",
"price": 3.99
},
...
]
}
Note: When carts and items are created, unique identifiers are
generated within PostgeSQL. subtotal
and total
are calculated off
of each item price
, the total tax amount (taxes
), and the discount
percentage (discount
). taxes
is calculated from another relational
called tax
which contains all tax percentages to compute against the
subtotal
.
GET /api/v1/view/cart/id
: Fetches all unique identifiers of shopping carts from backend database and returns a JSON array response, example:[1, 2, 3, 4, 5, ...]
Note: If cart records are not found, the above request will return an empty JSON array.
GET /api/v1/view/cart/[id]
: Fetches a cart record by given unique identifier id
from backend database and returns a JSON object with all data on cart record and an array of JSON object with data on all attached item records, example:{
"id": 1,
"subtotal": 6.98,
"discount": 0,
"taxes": 0.91, // Computed off of Canadian HST tax
"total": 7.89,
"items": [
{
"label": "Milk",
"price": 2.99
},
{
"label": "Cereal",
"price": 3.99
}
]
}
Note: If the cart record is not found, the above request will return an empty JSON object.
GET /api/v1/view/item/id
: Fetches all unique identifiers of shopping cart items from backend database and returns a JSON array response.Note: If item records are not found, the above request will return an empty JSON array.
POST /api/v1/edit/cart/[id]
: Updates a cart record by given unique identifier id
and updated to values specified by a passed JSON object with their attributes. For updating carts only the discount
attribute can be updated as others are prevented by constraint(s) or are calculated. Returns a JSON object with all data on cart record. Example of input data:{
"discount": 0.2 // updates current discount to 20%
}
Note: If the cart record is not found, the above request will return a 404 error with a JSON object with details.
POST /api/v1/edit/item/[id]
: Updates an item record by given unique identifier id
and updated to values specified by a passed JSON object with their attributes. For updating items only the label
and price
attribute can be updated. Updating the price
will also update the subtotal
, taxes
, and total
attributes in the attached cart record. Returns a JSON object with all data on item record. Examples of input data:Updating Label
{
"label": "Apple"
}
Updating Price
{
"price": 4.99
}
Updating Both
{
"label": "Apple",
"price": 4.99
}
Note: If the item record is not found, the above request will return a 404 error with a JSON object with details.
DELETE /api/v1/checkout/cart/[id]
: Deletes a cart record and all associated item records for a given cart id
. Returns a JSON object with all data on cart record and an array of JSON object with data on all attached item records.Note: If the cart record is not found, the above request will return a 404 error with a JSON object with details.
When error responses happen, the following JSON object is returned:
{
"status": "error",
"message": "<error message with details>"
}
404 Not Found: This happens when either an API URL does not exist or in some cases (mentioned above) there are no records that match a given id
.
400 Bad Request: This either means that some input data passed was invalid or the request method is incorrect for a specific URI section. Examples:
GET /api/v1/view/cart/a
DELETE /api/v1/add
POST /api/v1/edit/cart/1
with passed { "foo": bar }
500 Internal Server: This happens when something is wrong with database connectivity or query execution. When this happens, ensure that the target instance of PostgreSQL is running, DATABASE_URL
environment variable is set to the target correctly, and all barriers to make the connect are down (i.e. firewalls, open ports). It is also worth checking the server console for details when this happens. If you are a user, contact the server administrator to report this issue.
As with running the service, ensure there is a target PostgreSQL database running with the DATABASE_URL
environment variable set to its url before running the tests.
Unit tests can be ran using the following:
yarn test
See LICENSE licence details.
Generated using TypeDoc