Airbean is a fictional app where users can order coffee delivered by drones. The objective of this project was to create a REST API to handle all backend functionalities needed by the app. This is an individual examination project that builds on a previous group project by adding new features.
This project is built using Node.js and Express.
- Guest Users: Can view the menu and place orders, receiving an order confirmation upon purchase.
- Registered Users: Can view their order history.
- Admin Users: Can add, remove, and edit items in the menu.
Method | Endpoint | Description |
---|---|---|
GET | /about | About Us |
GET | /order | Menu |
Method | Endpoint | Description |
---|---|---|
POST | /cart | Add to Cart |
GET | /cart | View Cart |
DELETE | /cart/:id | Remove Item |
POST | /order | Place Order |
GET | /order/:orderid | Order Confirmation |
Method | Endpoint | Description |
---|---|---|
POST | /account/register | Register |
POST | /account/login | Login |
GET | /account/status | Login Status |
GET | /account/orders | Order History |
GET | /account/details | Account Details |
POST | /account/logout | Logout |
Method | Endpoint | Description |
---|---|---|
POST | /admin/register | Register |
POST | /admin/login | Login |
GET | /admin/status | Login Status |
POST | /admin/logout | Logout |
POST | /admin/create-item | Add Item |
PUT | /admin/:itemId | Edit Item |
GET | /admin/:itemId | View Item |
DELETE | /admin/:itemId | Remove Item |
POST | /admin/special-offers | Create Offers |
Follow these steps to create a local copy and run the project:
- Clone the repository:
git clone https://github.com/Mayonesa90/Airbean-Individuell-examination.git
- Navigate to the project directory:
cd Airbean-Individuell-examination
- Install dependencies:
npm install
- Start the development server:
nodemon server.js
Authentication is required for certain endpoints. Users must register and log in to access these endpoints. Admin users have separate endpoints and privileges. Tokens are used for session management.
Common errors and their handling mechanisms are as follows:
- 400 Bad Request: Invalid input format or missing parameters.
- 401 Unauthorized: Invalid or missing authentication token.
- 403 Forbidden: Insufficient privileges to access the resource.
- 404 Not Found: Requested resource does not exist.
- 500 Internal Server Error: General server error.
GET /about
Response:
Company: Airbean Coffee
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Coffee Production:
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
GET /order
Response:
[
{
"itemId": "ebe43b87-6e1e-4d4e-ade6-59775fffd1f4",
"title": "Bryggkaffe",
"desc": "Bryggd på månadens bönor.",
"price": 39,
"createdAt": "2024-06-12 11:15:55",
"_id": "17riXwRrm0X8i2JX"
},
{
"itemId": "8fc394f3-f77c-41f6-9729-a41c738904d2",
"title": "Cortado",
"desc": "Bryggd på månadens bönor.",
"price": 39,
"createdAt": "2024-06-12 11:17:12",
"_id": "3mgdjOvrwRv1NB65"
},
{
"itemId": "3edc7d79-272d-4634-9a70-c443d884cf59",
"title": "Cappuccino",
"desc": "Bryggd på månadens bönor.",
"price": 49,
"createdAt": "2024-06-12 11:16:40",
"_id": "QuMa7T5k1zBdtSPY"
},
{
"itemId": "57dc10d2-825f-4459-8e67-82f8afefd3cd",
"title": "Caffè Doppio",
"desc": "Bryggd på månadens bönor.",
"price": 49,
"createdAt": "2024-06-12 11:16:33",
"_id": "SVYrI2Z0sk9qlb0k"
},
{
"itemId": "c6da1417-ed2f-4d18-804b-663369f68230",
"title": "Latte Macchiato",
"desc": "Bryggd på månadens bönor.",
"price": 49,
"createdAt": "2024-06-12 11:16:47",
"_id": "V11mbtL34TIckABf"
},
{
"itemId": "a60b8fbb-3f1b-45ca-b67d-2d66c8d59b98",
"title": "Kaffe Latte",
"desc": "Bryggd på månadens bönor.",
"price": 54,
"createdAt": "2024-06-12 11:17:02",
"_id": "mqhyexrnHJ9AQXgS"
},
{
"itemId": "f7c602c7-0e35-4769-a559-3c9fa24bbff1",
"title": "Cortado",
"desc": "Bryggd på månadens bönor.",
"price": 39,
"createdAt": "2024-06-12 14:36:59",
"_id": "pK6rWtmhamtxldO7"
}
]
Instructions: Here you need the itemId
from the menu and use it in the request
POST /cart
Request syntax:
{
"id": "3edc7d79-272d-4634-9a70-c443d884cf59"
}
Response if item exists in menu:
Cappucino (49 kr) was successfully added to cart
404 Not found Error handling: if item does not exists in menu:
The requested product could not be found
GET /cart
Response if something is in cart:
Cart:
- 2024-06-13: Cappuccino, 49 kr
- 2024-06-14: Bryggkaffe, 39 kr
Total: 88kr
Error handling: 404 Not found
Cart is empty :/
To delete an item from the cart you need to enter the itemId as path parameter
DEL /cart/:id
Response if item exists in cart:
{
"message": "Item with id: 3edc7d79-272d-4634-9a70-c443d884cf59 successfully deleted from cart"
}
Error handling: 404 Not found
{
"message": "Item not found in cart"
}
POST /order
Response if items exist in cart:
{
"userId": "guest",
"items": [
{
"userId": "guest",
"productId": "ebe43b87-6e1e-4d4e-ade6-59775fffd1f4",
"title": "Bryggkaffe",
"price": 39,
"date": "2024-06-14",
"_id": "6Fq5Tpm8FVlXNlMu"
}
],
"total": 39,
"orderDate": "2024-06-14 11:38:53",
"estimatedDeliveryTime": "2024-06-14T10:08:53.003Z",
"orderId": "5a2fc9be-0bf5-45c5-abdf-d508bf8caf72"
}
Error handling: 404 Not found
Cart is empty
GET /order/:orderid
Response if orderId is correct:
Order confirmation
Bryggkaffe 39 kr
Bryggkaffe 39 kr
Total: 78 kr
Estimated delivery time: Fri Jun 14 2024 12:12:32 GMT+0200 (centraleuropeisk sommartid)
Orderid: 700a3ea4-ef09-42c7-a58a-da15a06ebe3e
Error handling: 404 Not found:
Order not found
POST /account/register
Request syntax:
{
"username": "Ivy",
"password": "Poison"
}
Respose if username and password input is valid:
{
"userId": "75cb8f18-0c45-4785-a513-7ae720c69cf4"
}
Error handling: 400 Bad request
{
"error": "Invalid username" || "Invalid password"
}
POST /account/login
Request syntax:
{
"username": "Ivy",
"password": "Poison"
}
Response if username and password is correct:
User Ivy was successfully logged in. Login status is: true
Error handling: 401 Unauthorized
Username or password was incorrect
GET /account/status
Response:
Login status is: true || false
GET /account/order/orders
Response if there are registered orders on user:
[
{
"orderId": "586d27c6-66fb-47c1-a43f-f16efca0a5d4",
"orderDate": "2024-06-13 14:32:54",
"total": 147,
"items": [
{
"title": "Caffè Doppio",
"price": 49
},
{
"title": "Caffè Doppio",
"price": 49
},
{
"title": "Caffè Doppio",
"price": 49
}
]
}
]
Error handling: 404 Not found
Orders not found
GET /account/users/account-details
Response if user is logged in:
{
"userId": "cc368198-8a3f-42ce-9b2e-ba8187b310f6",
"username": "Pika",
"password": "Chu",
"_id": "Dp0mFRwrtEd3DtcA"
}
POST /account/logout
Response if successful:
User was successfully logged out and cart cleared. Login status is: false, Items removed from cart: 0
401 Unauthorized
You need to log in first
POST /admin/register
Request syntax:
{
"username": "Bat",
"password": "Woman"
}
Response if username and password is valid:
{
"userId": "427db4fe-a3c0-44e8-a335-641098b76eeb"
}
Error handling: 400 Bad request
{
"error": "Invalid username" || "Invalid password"
}
POST /admin/login
Request syntax:
{
"username": "Bat",
"password": "Woman"
}
Response if username and password is correct:
Admin login: Bat was successfully logged in.
Error handling 401 Unauthorized
Username or password was incorrect
GET /admin/status
Response if admin is logged in:
Login status is: true
POST /admin/logout
Response if successfull:
Admin was successfully logged out. Login status is: false.
POST /admin/create-item
Request syntax:
{
"title": "Mojito",
"desc": "Mynta och romdrink",
"price": 109
}
Response if title, desc and price are valid:
{
"itemId": "3b33c3e4-ca40-40e9-bf88-e674af26728c"
}
Error handling: 400 Bad Request
{
"error": "Invalid or missing title" || "Invalid or missing desc" || "Invalid or missing price"
}
Add the itemId as path parameter
GET /admin/:itemId
Response if itemId is valid:
{
"itemId": "f7c602c7-0e35-4769-a559-3c9fa24bbff1",
"title": "Cortado",
"desc": "Bryggd på månadens bönor.",
"price": 39,
"createdAt": "2024-06-12 14:36:59",
"_id": "pK6rWtmhamtxldO7"
}
Error handling: 404 Not Found
{
"error": "Item not found"
}
Add the itemId as path parameter
DELETE /admin/:itemId
Response if itemId is valid:
"Number of items removed: 1. Item with id 3b33c3e4-ca40-40e9-bf88-e674af26728c successfully deleted"
Error handling: 404 Not Found
{
"error": "Item not found"
}
Add the itemId as path parameter
PUT /admin/:itemId
Request syntax (here you only add the field/fields of what you want to change):
{
"desc": "Coffee beans from Colombias finest producers",
}
Response if itemId is correct and input is valid:
{
"itemId": "f7c602c7-0e35-4769-a559-3c9fa24bbff1",
"title": "Cortado",
"desc": "Coffee beans from Colombias finest producers",
"price": 39,
"createdAt": "2024-06-12 14:36:59",
"_id": "pK6rWtmhamtxldO7",
"modifiedAt": "2024-06-14 12:43:17"
}
Error handling if itemId is wrong: 404 Not Found
{
"error": "Item not found"
}
Error handling when input is not valid:
{
"error": "Invalid or missing title" || "Invalid or missing desc" || "Invalid or missing price"
}
POST /admin/special-offers
Request syntax:
{
"item1": "3edc7d79-272d-4634-9a70-c443d884cf59",
"item2": "3edc7d79-272d-4634-9a70-c443d884cf59"
}
Response if both items exists in menu:
{
"offerId": "3191e7ca-9463-4faf-a950-48187909b1ef",
"item1": {
"itemId": "3edc7d79-272d-4634-9a70-c443d884cf59",
"title": "Cappuccino",
"desc": "Bryggd på månadens bönor.",
"price": 49,
"createdAt": "2024-06-12 11:16:40",
"_id": "QuMa7T5k1zBdtSPY"
},
"item2": {
"itemId": "3edc7d79-272d-4634-9a70-c443d884cf59",
"title": "Cappuccino",
"desc": "Bryggd på månadens bönor.",
"price": 49,
"createdAt": "2024-06-12 11:16:40",
"_id": "QuMa7T5k1zBdtSPY"
},
"priceForBoth": 78.4,
"discount": 19.6,
"createdAt": "2024-06-12 14:44:58",
"_id": "ksELIkXMXVVBPMrc"
}
Error handling if items do not exist i menu:
{
"error": "Item1 not found" || "Item2 not found"
}
401 Unauthorized
You need to log in as admin first