/shopping-api

Shopping api made in bun with elysia and drizzle orm

Primary LanguageTypeScript

Shopping API Application

About the project

This is a RESTful API for a shopping application.

Built With

Elysia

Drizzle-Orm

Getting Started

To get started with this project, run the steps below.

Prerequisites

To run this project, you will need:

Installation

  1. Clone the repo
git clone https://github.com/EdlanioJ/shopping-api.git
  1. Install NPM packages
bun install
  1. 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

Run

bun run dev

API Documentation

Open http://localhost:3000/docs to see the API documentation.

Rest API

Authentication

Register

Create a new user

Request
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" }'
Response
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

Login to your account

Request
POST /auth/login
curl --request 'POST' --url 'http://localhost:3000/auth/login' --header 'Content-Type: application/json' --data '{ "email": "foo@example.com", "password": "12345672" }'
Response
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": ""
}
  

Addresses

Get Addresses

Get all addresses

Request
GET /addresses/
curl --request 'GET' --url 'http://localhost:3000/addresses/' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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 Address

Add a new address

Request
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" }'
Response
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 Addresses

Count all addresses

Request
GET /addresses/count
curl --request 'GET' --url 'http://localhost:3000/addresses/count' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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 shipping address

Request
GET /addresses/shipping
curl --request 'GET' --url 'http://localhost:3000/addresses/shipping' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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

Update shipping address

Request
PUT /addresses/shipping/{addressId}
curl --request 'PUT' --url 'http://localhost:3000/addresses/shipping/mz2nk6csoc6p2mewmfoya8s4'
Response
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

Cart

Add Product to Cart

Add a product to cart

Request
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 }] }'
Response
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 Product in Cart

Update a product in cart

Request
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 }'
Response
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

Get cart items

Request
GET /cart/
curl --request 'GET' --url 'http://localhost:3000/cart/?pageIndex=0' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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

Request
GET /cart/price
curl --request 'GET' --url 'http://localhost:3000/cart/price' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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 Cart Ptoduct

Delete a product from cart

Request
DELETE /cart/{productId}
curl --request 'DELETE' --url 'http://localhost:3000/cart/mz2nk6csoc6p2mewmfoya8s4' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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

Favorites

Add Product to Favorite

Add a product to favorite

Request
POST /favorites/{productId}
curl --request 'POST' --url 'http://localhost:3000/favorites/mz2nk6csoc6p2mewmfoya8s4' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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 Product from Favorite

Remove a product from favorite

Request
DELETE /favorites/{productId}
curl --request 'DELETE' --url 'http://localhost:3000/favorites/mz2nk6csoc6p2mewmfoya8s4' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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 favorite products

Request
GET /favorites/
curl --request 'GET' --url 'http://localhost:3000/favorites/?pageIndex=0' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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 Products from Favorite to Cart

Move a product from favorite to cart

Request
POST /favorites/cart
curl --request 'POST' --url 'http://localhost:3000/favorites/cart' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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

Orders

Get Orders

Get all orders

Request
GET /orders/
curl --request 'GET' --url 'http://localhost:3000/orders/?status=processing&pageIndex=0' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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

Add order items

Request
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 }] }'
Response
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 Orders

Count all orders

Request
GET /orders/count
curl --request 'GET' --url 'http://localhost:3000/orders/count' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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
}

Products

Get Products

Get all products

Request
GET /products/
curl --request 'GET' --url 'http://localhost:3000/products/?category=popular&pageIndex=0' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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 Product By Id

Get a product by id

Request
GET /products/:id
  curl --request 'GET'  --url 'http://localhost:3000/products/mz2nk6csoc6p2mewmfoya8s4' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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
}

Product Reviews

Request
GET /products/:id/reviews
curl --request 'GET'  --url 'http://localhost:3000/products/mz2nk6csoc6p2mewmfoya8s4/reviews?pageIndex=0' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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
}

Reviews

Get User Reviews

Get all reviews of a user

Request
GET /reviews/me
curl --request 'GET' --url 'http://localhost:3000/reviews/me?pageIndex=0' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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 Reviews Count

Get the count of all reviews of a user

Request
GET /reviews/count
curl --request 'GET' --url 'http://localhost:3000/reviews/count' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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
}

Profile

Get User Profile

Get the user profile

Request
GET /profile/
curl --request 'GET' --url 'http://localhost:3000/profile/' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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 Profile

Update the user profile

Request
PATCH /profile/
  curl --request 'PATCH' --url 'http://localhost:3000/profile/' --header 'Authorization: Bearer YOUR_TOKEN' --data '{ "name": "…", "imageUrl": "…" }'
Response
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

Upload Image

Upload an image

Request
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'
Response
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: "…"
}

Payment

Create intents

Create a payment intent

Request
  POST /payment/intents
curl --request 'POST' --url 'http://localhost:3000/payment/intents' --header 'Authorization: Bearer YOUR_TOKEN' --data '{ "amount": 100000 }'
Response
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": ""
}

Notifications

Get Notifications

Get all notifications of a user

Request
GET /notifications
curl --request 'GET' --url 'http://localhost:3000/notifications?pageIndex=0' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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
}

Checkout

Create Checkout

Create a checkout

Request
POST /checkout
curl --request 'POST' --url 'http://localhost:3000/checkout' --header 'Authorization: Bearer YOUR_TOKEN'
Response
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

Categories

Get All Categories

Get all categories

Request
GET /categories
curl --request 'GET' --url 'http://localhost:3000/categories'
Response
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": ""
  }
]

License

This project is under the MIT license. See the LICENSE file for more details.

Made with ❤️ por Edlâneo Manuel 👋