GrubDash is a fictional company that operates an online food ordering and food delivery platform.
For this Thinkful project, I set up a RESTful API, wrote custom validation functions, created route handlers, and built specific API endpoints. Of note, the front-end application was provided for this assignment.
- Built with Node.js and Express server framework
All requests return JSON response. All post requests require application/json body, and return JSON response.
Get Dishes: GET to /dishes
- Requests all existing dish data.
- Successful GET requests will return an array of JSON objects representing the saved dishes. The response from the server should look like the following:
{
"data": [
{
"id": "d351db2b49b69679504652ea1cf38241",
"name": "Dolcelatte and chickpea spaghetti",
"description": "Spaghetti topped with a blend of dolcelatte and fresh chickpeas",
"price": 19,
"image_url": "https://images.pexels.com/photos/1279330/pexels-photo-1279330.jpeg?h=530&w=350"
}
// ...
]
}
Create New Dish: POST to /dishes
- POST request will be sent with a single JSON object like so:
{
"data": {
"name": "Dolcelatte and chickpea spaghetti",
"description": "Spaghetti topped with a blend of dolcelatte and fresh chickpeas",
"price": 19,
"image_url": "https://images.pexels.com/photos/1279330/pexels-photo-1279330.jpeg?h=530&w=350"
}
}
- Successful POST requests will return the newly created dish as a JSON object. The response from the server should look like the following:
{
"data": {
"id": "d351db2b49b69679504652ea1cf38241",
"name": "Dolcelatte and chickpea spaghetti",
"description": "Spaghetti topped with a blend of dolcelatte and fresh chickpeas",
"price": 19,
"image_url": "https://images.pexels.com/photos/1279330/pexels-photo-1279330.jpeg?h=530&w=350"
}
}
Get Specific Dish: GET to /dishes/:dishId
- Requests a specific dish by
:dishId
- Successful GET requests will return a JSON object. The response from the server should look like this:
{
"data": {
"id": "d351db2b49b69679504652ea1cf38241",
"name": "Dolcelatte and chickpea spaghetti",
"description": "Spaghetti topped with a blend of dolcelatte and fresh chickpeas",
"price": 19,
"image_url": "https://images.pexels.com/photos/1279330/pexels-photo-1279330.jpeg?h=530&w=350"
}
}
Update a Dish: PUT to /dishes/:dishId
- PUT request will be sent with a single JSON object like so:
{
"data": {
"id": "3c637d011d844ebab1205fef8a7e36ea",
"name": "Century Eggs",
"description": "Whole eggs preserved in clay and ash for a few months",
"image_url": "some-valid-url",
"price": "17"
}
}
- Note: The
id
property isn't required in the body of the request, but if it is present, it must match:dishId
from the route. - The response from the server should look like the following:
{
"data": {
"id": "3c637d011d844ebab1205fef8a7e36ea",
"name": "Century Eggs",
"description": "Whole eggs preserved in clay and ash for a few months",
"image_url": "some-valid-url",
"price": "17"
}
}
Get Orders: GET to /orders
- Requests a list of all existing order data.
- Successful GET requests will return an array of JSON objects representing the saved orders. The response from the server should look like the following:
{
"data": [
{
"id": "5a887d326e83d3c5bdcbee398ea32aff",
"deliverTo": "308 Negra Arroyo Lane, Albuquerque, NM",
"mobileNumber": "(505) 143-3369",
"status": "delivered",
"dishes": [
{
"id": "d351db2b49b69679504652ea1cf38241",
"name": "Dolcelatte and chickpea spaghetti",
"description": "Spaghetti topped with a blend of dolcelatte and fresh chickpeas",
"image_url": "https://images.pexels.com/photos/1279330/pexels-photo-1279330.jpeg?h=530&w=350",
"price": 19,
"quantity": 2
}
// ...
]
}
// ...
]
}
Create New Order: POST to /orders
- POST request will be sent with a single JSON object like so:
{
"data": {
"deliverTo": "308 Negra Arroyo Lane, Albuquerque, NM",
"mobileNumber": "(505) 143-3369",
"status": "delivered",
"dishes": [
{
"id": "d351db2b49b69679504652ea1cf38241",
"name": "Dolcelatte and chickpea spaghetti",
"description": "Spaghetti topped with a blend of dolcelatte and fresh chickpeas",
"image_url": "https://images.pexels.com/photos/1279330/pexels-photo-1279330.jpeg?h=530&w=350",
"price": 19,
"quantity": 2
}
]
}
}
- Note: Each dish in the Order's
dishes
property is a complete copy of the dish, rather than a reference to the dish by ID. This is so the order does not change retroactively if the dish data is updated some time after the order is created. - Successful POST requests will return the newly created order as a JSON object. The response from the server should look like the following:
{
"data": {
"id": "5a887d326e83d3c5bdcbee398ea32aff",
"deliverTo": "308 Negra Arroyo Lane, Albuquerque, NM",
"mobileNumber": "(505) 143-3369",
"status": "delivered",
"dishes": [
{
"id": "d351db2b49b69679504652ea1cf38241",
"name": "Dolcelatte and chickpea spaghetti",
"description": "Spaghetti topped with a blend of dolcelatte and fresh chickpeas",
"image_url": "https://images.pexels.com/photos/1279330/pexels-photo-1279330.jpeg?h=530&w=350",
"price": 19,
"quantity": 2
}
]
}
}
Get Order by ID: GET to /orders/:orderId
- Requests a specific order by
:orderId
- Successful GET requests will return a JSON object. The response from the server should look like this:
{
"data": {
"id": "f6069a542257054114138301947672ba",
"deliverTo": "1600 Pennsylvania Avenue NW, Washington, DC 20500",
"mobileNumber": "(202) 456-1111",
"status": "out-for-delivery",
"dishes": [
{
"id": "90c3d873684bf381dfab29034b5bba73",
"name": "Falafel and tahini bagel",
"description": "A warm bagel filled with falafel and tahini",
"image_url": "https://images.pexels.com/photos/4560606/pexels-photo-4560606.jpeg?h=530&w=350",
"price": 6,
"quantity": 1
}
]
}
}
Update Order: PUT to /orders/:orderId
- PUT request will be sent with a single JSON object like so:
{
"data": {
"deliverTo": "Rick Sanchez (C-132)",
"mobileNumber": "(202) 456-1111",
"status": "delivered",
"dishes": [
{
"id": "90c3d873684bf381dfab29034b5bba73",
"name": "Falafel and tahini bagel",
"description": "A warm bagel filled with falafel and tahini",
"image_url": "https://images.pexels.com/photos/4560606/pexels-photo-4560606.jpeg?h=530&w=350",
"price": 6,
"quantity": 1
}
]
}
}
- Note: The
id
property isn't required in the body of the request, but if it is present, it must match:orderId
from the route. - The response from the server should look like the following:
{
"data": {
"id": "f6069a542257054114138301947672ba",
"deliverTo": "Rick Sanchez (C-132)",
"mobileNumber": "(202) 456-1111",
"status": "delivered",
"dishes": [
{
"id": "90c3d873684bf381dfab29034b5bba73",
"name": "Falafel and tahini bagel",
"description": "A warm bagel filled with falafel and tahini",
"image_url": "https://images.pexels.com/photos/4560606/pexels-photo-4560606.jpeg?h=530&w=350",
"price": 6,
"quantity": 1
}
]
}
}
Delete Order: DELETE to /orders/:orderId
- DELETE request will be sent without a request body.
- Note: If the given
:orderId
does not match an existing order, the server should respond with404
. - A successful DELETE request will result in a response status code of 204 and no response body.