Skip to content

Yemeksepeti-Python-Bootcamp/BurgerZilla_Final_Project

Repository files navigation

Burgerzilla

Burgerzilla REST microservice provides order communication between customers and restaurants.
Restaurant owners can add, update and delete products.They can also manage their orders.
In addition, users can access and order the products of the restaurant. They can update and cancel their orders.

Main Packages

  • Flask
  • Flask-RESTX (community driven fork of Flask-RESTPlus)
  • Flask-SQLAlchemy
  • Flask-JWT-Extended
  • psycopg2-binary
  • flask_bcrypt

Burgerzilla File Structure

burgerzilla
├─ .gitignore
├─ app
│  ├─ api
│  │  ├─ restaurant
│  │  │  ├─ controller.py
│  │  │  ├─ dto.py
│  │  │  ├─ service.py
│  │  │  ├─ utils.py
│  │  │  └─ __init__.py
│  │  ├─ user
│  │  │  ├─ controller.py
│  │  │  ├─ dto.py
│  │  │  ├─ service.py
│  │  │  ├─ utils.py
│  │  │  └─ __init__.py
│  │  └─ __init__.py
│  ├─ auth
│  │  ├─ controller.py
│  │  ├─ dto.py
│  │  ├─ service.py
│  │  ├─ utils.py
│  │  └─ __init__.py
│  ├─ extensions.py
│  ├─ models
│  │  ├─ order.py
│  │  ├─ product.py
│  │  ├─ restaurant.py
│  │  ├─ schemas.py
│  │  ├─ user.py
│  │  ├─ usertype.py
│  │  └─ __init__.py
│  ├─ utils.py
│  └─ __init__.py
├─ boot.sh
├─ config.py
├─ docker-compose.yml
├─ Dockerfile
├─ requirements.txt
├─ run.py
└─ tests
   ├─ test_auth_api.py
   ├─ test_config.py
   ├─ test_restaurant_api.py
   ├─ test_restaurant_model.py
   ├─ test_user_api.py
   ├─ test_user_model.py
   ├─ utils
   │  ├─ base.py
   │  ├─ common.py
   │  └─ __init__.py
   └─ __init__.py

Database Design

DB_Schema.png

Run the app from Docker

To run the application, these 2 docker commands should be used.

docker build -t burgerzilla:latest .
docker compose up --build web

boot.sh includes a script which can put some initial data to our database.

After these two commands, application will be running on localhost:80

Run the app on local

For run the application on your local machine, create a virtual environment.
After you active the env, install requirements.txt and flask run!

virtualenv env
$ source env/bin/activate 
pip install -r requirements.txt
flask run

AUTH ENDPOINTS

Register and Login endpoints is inside 'auth' namespace.

Register

Request to: 127.0.0.1:80/auth/register

Request Type: POST

{
    "email":"ilhanmert@alan.com",
    "username":"ilhanmert",
    "name":"ilhan m alan",
    "password":"123",
    "usertype_id":1
}

usertype_id=1 if you are Restaurant Owner,
usertype_id=0 if you are Customer
Here, user_type is optional parameter and if not given it's default 0

Response

{
    "status": "True",
    "message": "Kayıt başarılı",
    "access_token": "eyJ0eX.....JnE",
    "user": {
        "id": 5,
        "email": "ilhanmert@alan.com",
        "usertype_id": 1,
        "name": "ilhan m alan",
        "username": "ilhanmert"
    }
}

Login

Request to: 127.0.0.1:80/auth/login

Request Type: POST

{
    "email":"ilhanmert@alan.com",
    "password":"123"
}

email and password is required

Response

{
    "status": "True",
    "message": "Giriş başarılı",
    "access_token": "eyJ0eX.....JnE",
    "user": {
        "id": 5,
        "email": "ilhanmert@alan.com",
        "usertype_id": 1,
        "name": "ilhan m alan",
        "username": "ilhanmert"
    }
}

USER ENDPOINTS

User(Customer) endpoints is inside 'api/user' namespace.

Get All Orders of a User

Request Type: GET

Request to: 127.0.0.1:80/api/user/orders

Response will be the all orders given by the authorized user.

Response

{
    "status": true,
    "message": "Orders loaded successfully",
    "orders": [
        {
            "product_id": 1,
            "orderdate": "2022-02-13T15:44:37.730014",
            "quantity": 1,
            "orderstatus": "CANCELLED",
            "restaurant_id": 2,
            "userid": 5,
            "id": 1,
            "address": "Kaer Morhen Sokak 15/3"
        },
        {
            "product_id": 2,
            "orderdate": "2022-02-13T16:05:28.180374",
            "quantity": 3,
            "orderstatus": "NEW",
            "restaurant_id": 2,
            "userid": 5,
            "id": 3,
            "address": "büyükdere mahallesi düzgün sokak 15/5"
        }
    ]
}

Get Order by ID

Request Type: GET

Request to: 127.0.0.1:80/api/user/orders/<order_id:int>

Response will be the specific order given by the authorized user.

Response

{
    "status": true,
    "message": "Order loaded successfully",
    "order": {
        "product_id": 1,
        "orderdate": "2022-02-13T15:44:37.730014",
        "quantity": 1,
        "orderstatus": "CANCELLED",
        "restaurant_id": 2,
        "userid": 5,
        "id": 1,
        "address": "Kaer Morhen Sokak 15/3"
    }
}

Create Order

Request to: 127.0.0.1:80/api/user/orders

Request Type: POST

        {
            "restaurant_id": 2,
            "product_id": 1,
            "quantity":2,
            "address":"büyükdere mahallesi düzgün sokak 15/5"
        }

Response

{
    "status": true,
    "message": "Order created successfully",
    "order": {
        "restaurant_id": 2,
        "id": 1,
        "userid": 5,
        "quantity": 2,
        "orderdate": "2022-02-13T15:44:37.730014",
        "address": "büyükdere mahallesi düzgün sokak 15/5",
        "orderstatus": "NEW",
        "product_id": 1
    }
}

Update Order

Request to: 127.0.0.1:80/api/user/orders/<order_id:int>

Request Type: PUT

{
    "quantity":"1",
    "product_id":"1",
    "address":"Kaer Morhen Sokak 15/3"
}

To update, you can change quantity, address or product that you ordered IF the order_status is still 'NEW'

Response

{
    "status": true,
    "message": "Order updated successfully",
    "order": {
        "restaurant_id": 2,
        "id": 1,
        "userid": 5,
        "quantity": 1,
        "orderdate": "2022-02-13T15:44:37.730014",
        "address": "Kaer Morhen Sokak 15/3",
        "orderstatus": "NEW",
        "product_id": 1
    }
}

Cancel Order

Request to: 127.0.0.1:80/api/user/orders/cancel/<order_id:int>

Request Type: PUT

Don't need a send body for the cancel request.

Make put request the given url with order_id

Response

{
    "status": true,
    "message": "Order cancelled successfully",
    "order": {
        "product_id": 1,
        "orderdate": "2022-02-13T15:44:37.730014",
        "quantity": 1,
        "orderstatus": "CANCELLED",
        "restaurant_id": 2,
        "userid": 5,
        "id": 1,
        "address": "Kaer Morhen Sokak 15/3"
    }
}

RESTAURANT ENDPOINTS

Restaurant endpoints is inside 'api/restaurant' namespace.

Get All Products of a Restaurant

Request Type: GET

Request to: 127.0.0.1:80/api/restaurant/<restaurant_id:int>/products

Response will be the all products of the restaurant.
Since it is the menu of the specified restaurant, token is not needed.

Response

{
    "status": true,
    "message": "Products loaded successfully",
    "products": [
        {
            "name": "Bombili",
            "id": 1,
            "price": 30.0,
            "description": "meşhur dombili burger, özel soslu ve sarımsaklı",
            "restaurant_id": 2,
            "image": "dombiliburger.jpg"
        },
        {
            "name": "Duble Peynirli",
            "id": 2,
            "price": 50.0,
            "description": "çift katlı mozarella çedar dombili burger",
            "restaurant_id": 2,
            "image": "dublepeynir.jpg"
        }
    ]
}

Get Specific Product From a Specific Restaurant

Request Type: GET

Request to: 127.0.0.1:80/api/restaurant/<restaurant_id:int>/products/<product_id:int>

Response will be the single product of given restaurant.
Since it is a part of menu of the specified restaurant, token is not needed.

Response

{
    "status": true,
    "message": "Product loaded successfully",
    "product": {
        "name": "Duble Peynirli",
        "id": 2,
        "price": 50.0,
        "description": "çift katlı mozarella çedar dombili burger",
        "restaurant_id": 2,
        "image": "dublepeynir.jpg"
    }
}

Create Product

Request to: 127.0.0.1:80/api/user/products

Request Type: POST

Restaurant owners can add new products to their restaurant from here.
Token is needed to authorize restaurant owner.

        {
            "name": "Duble Peynirli",
            "description": "çift katlı mozarella çedar dombili burger",
            "price": 50,
            "image": "dublepeynir.jpg"
        }

Response

{
    "status": true,
    "message": "Product created successfully",
    "product": {
        "price": 50.0,
        "restaurant_id": 2,
        "image": "dublepeynir.jpg",
        "description": "çift katlı mozarella çedar dombili burger",
        "id": 2,
        "name": "Duble Peynirli"
    }
}

Get All Orders of a Restaurant

Request Type: GET

Request to: 127.0.0.1:80/api/restaurant/<restaurant_id:int>/orders

Response will be the all orders of the restaurant.
Only restaurant owner can see, so token is needed.

Response

{
    "status": true,
    "message": "Orders loaded successfully",
    "orders": [
        {
            "product_id": 1,
            "id": 1,
            "orderdate": "2022-02-13T15:44:37.730014",
            "quantity": 1,
            "userid": 5,
            "orderstatus": "CANCELLED",
            "address": "Kaer Morhen Sokak 15/3",
            "restaurant_id": 2
        },
        {
            "product_id": 2,
            "id": 2,
            "orderdate": "2022-02-13T15:47:23.831123",
            "quantity": 2,
            "userid": 4,
            "orderstatus": "DELIVERED",
            "address": "Isildur Mh 111sk",
            "restaurant_id": 2
        },
        {
            "product_id": 2,
            "id": 3,
            "orderdate": "2022-02-13T16:05:28.180374",
            "quantity": 3,
            "userid": 5,
            "orderstatus": "NEW",
            "address": "büyükdere mahallesi düzgün sokak 15/5",
            "restaurant_id": 2
        }
    ]
}

Get Specific Order By ID

Request Type: GET

Request to: 127.0.0.1:80/api/restaurant/<restaurant_id:int>/orders/<order_id:int>

Response will be the single order of given restaurant.
Since it is a restaurant endpoint, only restaurant owner can see, so bearer token is needed.

Response

{
    "status": true,
    "message": "Order loaded successfully",
    "order": {
        "product_id": 2,
        "id": 3,
        "orderdate": "2022-02-13T16:05:28.180374",
        "quantity": 3,
        "userid": 5,
        "orderstatus": "NEW",
        "address": "büyükdere mahallesi düzgün sokak 15/5",
        "restaurant_id": 2
    }
}

Update Order

Request to: 127.0.0.1:80/api/restaurant/orders/<order_id:int>

Request Type: PUT

Request Body

Restaurant owner can change the status of the order, bearer token is needed

{
    "orderstatus":"DELIVERED"
}

Response

{
    "status": true,
    "message": "Order updated successfully",
    "order": {
        "product_id": 2,
        "id": 3,
        "orderdate": "2022-02-13T16:05:28.180374",
        "quantity": 3,
        "userid": 5,
        "orderstatus": "DELIVERED",
        "address": "büyükdere mahallesi düzgün sokak 15/5",
        "restaurant_id": 2
    }
}

Additional Endpoints

Create Restaurant

Request to: 127.0.0.1:80/api/restaurant/

Request Type: POST

Can create restaurant by using this endpoint.
Token is needed.

{
    "name":"Dombili Burger2"
}

Response

{
    "status": true,
    "message": "Restaurant created successfully",
    "restaurant": {
        "id": 3,
        "name": "Dombili Burger2",
        "userid": 3
    }
}

Update Restaurant by ID

Request to: 127.0.0.1:80/api/restaurant/<restaurant_id:int>

Request Type: PUT

Request Body

Restaurant owner can change the name of the restaurant, bearer token is needed

{
    "name":"NewName Restoran"
}

Response

{
    "status": true,
    "message": "Restaurant updated successfully",
    "restaurant": {
        "id": 1,
        "name": "NewName Restoran",
        "userid": 3
    }
}

Get User's Restaurant

Request to: 127.0.0.1:80/api/restaurant/user

Request Type: GET

Get all restaurants of a user. Token is needed to identify user whether if restaurant owner or not.

Response

{
    "status": true,
    "message": "Restaurants loaded successfully",
    "restaurants": [
        {
            "id": 3,
            "name": "Dombili Burger2",
            "userid": 3
        },
        {
            "id": 1,
            "name": "Updated Restoran",
            "userid": 3
        }
    ]
}
   

Delete Restaurant by Restaurant ID

Request to: 127.0.0.1:80/api/restaurant/<restaurant_id:int>

Request Type: DELETE

Delete restaurant by restaurant id. Token is needed.

Response

{
    "status": true,
    "message": "Restaurant deleted successfully",
    "restaurant": {
        "id": 1,
        "name": "Dombili Burger",
        "userid": 3
    }
}
   

Get Restaurant by Restaurant ID

Request to: 127.0.0.1:80/api/restaurant/<restaurant_id:int>

Request Type: GET

GET restaurant by restaurant id. Token is needed.

Response

{
    "status": true,
    "message": "Restaurant loaded successfully",
    "restaurant": {
        "id": 5,
        "name": "Dombili Burger2",
        "userid": 3
    }
}
   

Get User Details

Request to: localhost:80/api/user

Request Type: GET

GET user details. Token is needed.

Response

{
    "status": true,
    "message": "User data sent",
    "user": {
        "usertype_id": 1,
        "id": 3,
        "username": "omerk",
        "name": "Ömer Kandor",
        "email": "omerk@restoran.nett"
    }
}
   

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages