This is a RESTful API for a shopping application.
To get started with this project, run the steps below.
To run this project, you will need:
- install bun.
- Create a free account in Uploadcare.
- Create a free account in Stripe.
- Clone the repo
git clone https://github.com/EdlanioJ/shopping-api.git
- Install NPM packages
bun install
- Enter your env variables in
.env.local
DATABASE_URL='ENTER DATABASE URL'
JWT_SECRET_KEY='ENTER JWT SECRET KEY'
UPLOADCARE_PUBLIC_KEY='ENTER UPLOADCARE PUBLIC KEY'
STRIPE_SECRET_KEY='ENTER STRIPE SECRET KEY'
// optional
PORT=ENTER PORT
bun run dev
Open http://localhost:3000/docs to see the API documentation.
Create a new user
POST /auth/register
curl --request 'POST' --url 'http://localhost:3000/auth/register' --header 'Content-Type: application/json' --data '{ "name": "Foo", "email": "foo@example.com", "password": "12345672" }'
HTTP/1.1 204 No Content
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
Access-Control-Exposed-Headers: *
Date: Fri, 22 Mar 2024 10:55:12 GMT
Content-Length: 0
Login to your account
POST /auth/login
curl --request 'POST' --url 'http://localhost:3000/auth/login' --header 'Content-Type: application/json' --data '{ "email": "foo@example.com", "password": "12345672" }'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Fri, 22 Mar 2024 11:55:52 GMT
Content-Length: 183
{
"accessToken": "…"
}
Get all addresses
GET /addresses/
curl --request 'GET' --url 'http://localhost:3000/addresses/' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Fri, 22 Mar 2024 14:35:40 GMT
Content-Length: 426
{
"addresses": [
{
"id": "…",
"name": "…",
"address": {
"street": "…",
"city": "…",
"state": "…",
"zipCode": "…",
"country": "…"
}
}
],
"shippingAddress": "…"
}
Add a new address
POST /addresses/
curl --request 'POST' --url 'http://localhost:3000/addresses/' --header 'Content-Type: application/json' --header 'Authorization: Bearer YOUR_TOKEN' --data '{ "name": "Foo", "street": "123 Fake St", "city": "Fake City", "state": "Fake State", "country": "Fake Country", "zipCode": "12345" }'
HTTP/1.1 204 No Content
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
Access-Control-Exposed-Headers: *
Date: Fri, 22 Mar 2024 14:35:40 GMT
Content-Length: 0
Count all addresses
GET /addresses/count
curl --request 'GET' --url 'http://localhost:3000/addresses/count' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Fri, 22 Mar 2024 14:35:40 GMT
Content-Length: 12
{
"count": 1
}
Get shipping address
GET /addresses/shipping
curl --request 'GET' --url 'http://localhost:3000/addresses/shipping' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Fri, 22 Mar 2024 14:35:40 GMT
Content-Length: 426
{
"id": "…",
"name": "…",
"address": {
"street": "…",
"city": "…",
"state": "…",
"zipCode": null,
"country": null
}
}
Update shipping address
PUT /addresses/shipping/{addressId}
curl --request 'PUT' --url 'http://localhost:3000/addresses/shipping/mz2nk6csoc6p2mewmfoya8s4'
HTTP/1.1 204 No Content
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: PUT
Access-Control-Exposed-Headers: *
Date: Fri, 22 Mar 2024 14:35:40 GMT
Content-Length: 0
Add a product to cart
POST /cart/
curl --request 'POST' --url 'http://localhost:3000/cart/' --header 'Authorization: Bearer YOUR_TOKEN' --header 'Content-Type: application/json' --data '{ "items": [{"productId": "mz2nk6csoc6p2mewmfoya8s4", "quantity": 1 }] }'
HTTP/1.1 204 No Content
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 17:17:27 GMT
Content-Length: 0
Update a product in cart
PUT /cart/{productId}
curl --request 'PUT' --url 'http://localhost:3000/cart/mz2nk6csoc6p2mewmfoya8s4' --header 'Authorization: Bearer YOUR_TOKEN' --header 'Content-Type: application/json' --data '{ "quantity": 2 }'
HTTP/1.1 204 No Content
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 17:17:27 GMT
Content-Length: 0
Get cart items
GET /cart/
curl --request 'GET' --url 'http://localhost:3000/cart/?pageIndex=0' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 21:43:42 GMT
Content-Length: 297
{
"products": [
{
"id": "…",
"name": "…",
"image": "…",
"stock": 1,
"quantity": 1,
"priceInCents": 1
}
],
"totalInCents": 0,
"pageIndex": 0,
"perPage": 10,
"totalCount": 1
}
GET /cart/price
curl --request 'GET' --url 'http://localhost:3000/cart/price' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 21:43:42 GMT
Content-Length: 121
{
"totalInCents": 0
}
Delete a product from cart
DELETE /cart/{productId}
curl --request 'DELETE' --url 'http://localhost:3000/cart/mz2nk6csoc6p2mewmfoya8s4' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 204 No Content
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: DELETE
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 21:43:42 GMT
Content-Length: 0
Add a product to favorite
POST /favorites/{productId}
curl --request 'POST' --url 'http://localhost:3000/favorites/mz2nk6csoc6p2mewmfoya8s4' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 204 No Content
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 21:43:42 GMT
Content-Length: 0
Remove a product from favorite
DELETE /favorites/{productId}
curl --request 'DELETE' --url 'http://localhost:3000/favorites/mz2nk6csoc6p2mewmfoya8s4' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 204 No Content
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: DELETE
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 21:43:42 GMT
Content-Length: 0
Get favorite products
GET /favorites/
curl --request 'GET' --url 'http://localhost:3000/favorites/?pageIndex=0' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 21:43:42 GMT
Content-Length: 297
{
"products": [
{
"id": "…",
"name": "…",
"image": "…",
"priceInCents": 1
}
],
"pageIndex": 1,
"perPage": 10,
"totalCount": 1
}
Move a product from favorite to cart
POST /favorites/cart
curl --request 'POST' --url 'http://localhost:3000/favorites/cart' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 204 No Content
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 21:43:42 GMT
Content-Length: 0
Get all orders
GET /orders/
curl --request 'GET' --url 'http://localhost:3000/orders/?status=processing&pageIndex=0' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 21:43:42 GMT
Content-Length: 297
{
"orders": [
{
"id": "…",
"status": "…",
"totalInCents": 1,
"createdAt": "…",
"quantity": 1
}
],
"pageIndex": 0,
"perPage": 10,
"totalCount": 1
}
Add order items
POST /orders/
curl --request 'POST' --url 'http://localhost:3000/' --header 'Content-Type: application/json' --header 'Authorization: Bearer YOUR_TOKEN' --data '{ "items": [{ "productId": "mz2nk6csoc6p2mewmfoya8s4", "quantity": 1 }] }'
HTTP/1.1 204 No Content
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 21:43:42 GMT
Content-Length: 0
Count all orders
GET /orders/count
curl --request 'GET' --url 'http://localhost:3000/orders/count' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 21:43:42 GMT
Content-Length: 121
{
"count": 1
}
Get all products
GET /products/
curl --request 'GET' --url 'http://localhost:3000/products/?category=popular&pageIndex=0' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Fri, 22 Mar 2024 14:35:40 GMT
Content-Length: 426
{
"products": [
{
"id": "…",
"name": "…",
"image": "…",
"priceInCents": 0
}
],
"pageIndex": 0,
"perPage": 10,
"totalCount": 1
}
Get a product by id
GET /products/:id
curl --request 'GET' --url 'http://localhost:3000/products/mz2nk6csoc6p2mewmfoya8s4' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 17:17:27 GMT
Content-Length: 337
{
"id": "…",
"name": "…",
"image": "…",
"pricePriceInCents": 1,
"description": null,
"review": 1,
"rating": 1,
"isFavorite": true
}
GET /products/:id/reviews
curl --request 'GET' --url 'http://localhost:3000/products/mz2nk6csoc6p2mewmfoya8s4/reviews?pageIndex=0' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 17:17:27 GMT
Content-Length: 337
{
"product": {
"id": "…",
"name": "…",
"image": "…",
"reviewsCount": 0,
"ratingAvg": 0
},
"reviews": [
{
"id": "…",
"userName": "…",
"rating": 1,
"comment": "…",
"createdAt": "…"
}
],
"pageIndex": 0,
"perPage": 10
}
Get all reviews of a user
GET /reviews/me
curl --request 'GET' --url 'http://localhost:3000/reviews/me?pageIndex=0' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 17:17:27 GMT
Content-Length: 337
{
"reviews": [
{
"id": "…",
"rating": 0,
"comment": "…",
"productName": "…",
"createdAt": null,
"productId": "…",
"productImage": "…"
}
],
"pageIndex": 0,
"perPage": 10,
"totalCount": 1
}
Get the count of all reviews of a user
GET /reviews/count
curl --request 'GET' --url 'http://localhost:3000/reviews/count' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 17:17:27 GMT
Content-Length: 337
{
"count": 1
}
Get the user profile
GET /profile/
curl --request 'GET' --url 'http://localhost:3000/profile/' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 17:17:27 GMT
Content-Length: 337
{
"id": "…",
"name": "…",
"imageUrl": null,
"email": "…"
}
Update the user profile
PATCH /profile/
curl --request 'PATCH' --url 'http://localhost:3000/profile/' --header 'Authorization: Bearer YOUR_TOKEN' --data '{ "name": "…", "imageUrl": "…" }'
HTTP/1.1 204 No Content
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: PATCH
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 17:17:27 GMT
Content-Length: 0
Upload an image
POST /upload
curl --request 'POST' --url 'http://localhost:3000/upload' --header 'Authorization: Bearer YOUR_TOKEN' --header 'Content-Type: multipart/form-data' --form 'file=@path/to/file.jpg'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 17:17:27 GMT
Content-Length: 337
{
"uuid": "…",
imageUrl: "…"
}
Create a payment intent
POST /payment/intents
curl --request 'POST' --url 'http://localhost:3000/payment/intents' --header 'Authorization: Bearer YOUR_TOKEN' --data '{ "amount": 100000 }'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 17:17:27 GMT
Content-Length: 337
{
"paymentIntent": "…",
"ephemeralKey": "…",
"customerId": "…"
}
Get all notifications of a user
GET /notifications
curl --request 'GET' --url 'http://localhost:3000/notifications?pageIndex=0' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 17:17:27 GMT
Content-Length: 337
{
"notifications": [
{
"id": "…",
"type": "…",
"isOpened": null,
"createdAt": null,
"userId": null,
"data": null
}
],
"pageIndex": 1,
"perPage": 1,
"totalCount": 1
}
Create a checkout
POST /checkout
curl --request 'POST' --url 'http://localhost:3000/checkout' --header 'Authorization: Bearer YOUR_TOKEN'
HTTP/1.1 204 No Content
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 17:17:27 GMT
Content-Length: 0
Get all categories
GET /categories
curl --request 'GET' --url 'http://localhost:3000/categories'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Content-Type: application/json;charset=utf-8
Access-Control-Exposed-Headers: *
Date: Sat, 23 Mar 2024 17:17:27 GMT
Content-Length: 337
[
{
"name": "…",
"id": "…",
"createdAt": null,
"updatedAt": null,
"slug": "…"
}
]
This project is under the MIT license. See the LICENSE file for more details.
Made with ❤️ por Edlâneo Manuel 👋