A structured E-commerce REST API built to be the foundational backbone of a production-grade web app. Dev for hosting & new features such as a cart & payment is still ongoing.
Table of Contents
This project is the Capstone Project for the Udacity Full-Stack Web Developer Nanodegree program. The purpose of this REST API is to develop a template for the creation of custom modern E-commerce websites.
A list of helpful resources are listed in the acknowledgements.
- Python-3.7.9
- Flask
- PostgreSQL
- SQLAlchemy
- Auth0
- Heroku Backend Deployment
- Netlify Frontend Deployment
- Postman
- Next.js
Follow the instructions to install Python 3.7.9 for your platform in the python docs
Follow the instructions to install PostgreSQL locally for your platform on the PostgreSQL website
It is recommended to work within a virtual environment using venv for this project. This keeps dependencies organized for each project. Instructions for setting this up can be found here
Once the virtual environment is setup and running, install the pip dependencies by navigating to the root directory of the project and running:
pip3 install -r requirements.txtThis will install all required packages that are used for the Flask backend.
Follow the instructions to install npm at the following
link
While in the root directory of the project, run the following:
npm installThis will install the node-modules needed by referencing the package.json
file.
To set up Auth0 for this project, refer to the following steps:
- Sign up for a free account on the Auth0 website.
- Next, create a new single-page application with the name Flask-Ecommerce.
- In Application settings, input your root URL to Allowed Callback URLs,
Allowed Logout URLs, and Allowed
Web Origins. For example:
a.http://localhost:3000on all of the above for local hosting, or
b.https://HEROKU_APP_NAME.herokuapp.comfor your Heroku deployment. - Create an API in Auth0 with
RBACandAdd Permissions in the Access Tokenenabled in the API settings. - In the API's
Permissionstab, add the following permissions:
| Permission | Description |
|---|---|
| post:products | Adds new products |
| patch:products | Edits products |
| delete:products | Deletes products |
- Finally, add the
Roleof Admin to the API that has all of the above permissions. AddUserswith the Admin role in order for them to be authenticated to use the above HTTP requests.
- Admin: This role includes permissions for all endpoints in the Table of
Endpoints, as well as the
POST,PATCH, &DELETErequests shown above inStep 5. - Public: This role includes only
GETrequest permissions, as this will be for the users of the world to use. This role excludes any rights to manipulating the PostgreSQL database.
Create 2 .env files in the following locations following the .env.example
file format:
- In the directory
/backend/srcand - in the root directory.
NOTE: These environment variables will need to be added to the
Configure VarsSettings on your Heroku deployment app if using Heroku.
Currently, the Frontend is still in development, but the Backend REST API can be used/tested with Postman.
The preferred way to test the backend HTTP requests are to use Postman,
however, the Python Unittest file is included in /backend/src folder and is
titled test_app.py.
Refer to the documentation within the Postman Collection for details regarding setup.
NOTE: A JWT access token is needed for Postman testing. The JWT token must be from an authenticated user with the role of
Admin, which has all the necessary permissions.
The Python Unittest is located in the /backend folder titled test_app.py.
Run the tests following these steps:
-
Run the Flask server from the
/backend/srcdirectory virtual environment using these terminal bash commands:# This will run the flask app on port 5000 # On Linux: use `export` # On Windows: use `set` export FLASK_APP=app.py export FLASK_ENV=development flask run
-
Now that the Flask server is running locally, the python unit tests can be run with:
python3 test_app.py
- Base URL: The backend can only be run locally or viewed at the URL:
https://flask-ecommerce-rest-api.herokuapp.com/. When running locally, the backend app is
hosted at the default URL, http://127.0.0.1:5000/, which is set as a proxy in
the frontend configuration. This is the domain which must be used when making
API requests via
postmanorcurl. - Authentication: This version of the application does not require authentication or API keys.
Errors are returned as JSON objects in the following format:
{
"success": False,
"error": 400,
"message": "bad request"
}The API will return the five error type default responses when requests fail (unless custom response is assigned):
- 400: Bad Request
- 401: Unauthorized
- 403: Forbidden
- 404: Resource Not Found
- 422: Not Processable
- 500: Internal Server Error
Below is a table of the methods allowed for each of the 3 endpoints.
| Endpoints | Methods | |||
|---|---|---|---|---|
| GET | POST | PATCH | DELETE | |
| / | X | |||
| /collections | X | |||
| /collections/category_id | X | |||
| /collections/mens-apparel | X | |||
| /collections/mens-apparel/product_id | X | |||
| /collections/womens-apparel | X | |||
| /collections/womens-apparel/product_id | X | |||
| /collections/holiday | X | |||
| /collections/holiday/product_id | X | |||
| /collections/misc | X | |||
| /collections/misc/product_id | X | |||
| /products | X | X | X | X |
| /products/product_id | X |
- Collections:
- GET /collections
- GET /collections/category_id
- GET /collections/mens-apparel
- GET /collections/mens-apparel/product_id
- GET /collections/womens-apparel
- GET /collections/womens-apparel/product_id
- GET /collections/holiday
- GET /collections/holiday/product_id
- GET /collections/misc
- GET /collections/misc/product_id
- Products:
- Index:
Retrieves category collections from database:
$ curl -X GET http://127.0.0.1:5000/collections{
"category_info": [
{
"active": true,
"category_name": "Mens-Apparel",
"description": "This category is for mens apparel",
"id": 1,
"picture": "static/images/categories/mens_apparel"
},
{
"active": true,
"category_name": "Womens-Apparel",
"description": "This category is for womens apparel",
"id": 2,
"picture": "static/images/categories/womens_apparel"
},
{
"active": true,
"category_name": "Holiday",
"description": "This category is for holiday items",
"id": 3,
"picture": "static/images/categories/holiday"
},
{
"active": true,
"category_name": "Misc",
"description": "This category is for miscellaneous items",
"id": 4,
"picture": "static/images/categories/misc"
}
],
"success": true
}Retrieves specific category collection from database:
$ curl -X GET http://127.0.0.1:5000/collections/1{
"category_info": {
"active": true,
"category_name": "Mens-Apparel",
"description": "This category is for mens apparel",
"id": 1,
"picture": "static/images/categories/mens_apparel"
},
"success": true
}Retrieves mens-apparel collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/mens-apparel{{
"mens_apparel_data": [
{
"category_id": [
1
],
"id": 1,
"msrp": 25.0,
"picture": "static/images/products/1",
"product_description": "This is a tapered mens summer blue t-shirt.",
"product_name": "Mens Summer Blue Tee"
},
{
"category_id": [
1,
3
],
"id": 3,
"msrp": 40.0,
"picture": "static/images/products/3",
"product_description": "This is a husky red mens holiday sweater.",
"product_name": "Mens Holiday Sweater"
},
{
"category_id": [
1,
2,
3,
4
],
"id": 4,
"msrp": 12.0,
"picture": "static/images/products/4",
"product_description": "This is a pair of black holiday unisex socks.",
"product_name": "Holiday Unisex Socks"
}
],
"success": true
}Retrieves specific mens-apparel collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/mens-apparel/1{
"mens_apparel_data": {
"category_id": [
1
],
"id": 1,
"msrp": 25.0,
"picture": "static/images/products/1",
"product_description": "This is a tapered mens summer blue t-shirt.",
"product_name": "Mens Summer Blue Tee"
},
"success": true
}Retrieves womens-apparel collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/womens-apparel{
"success": true,
"womens_apparel_data": [
{
"category_id": [
2
],
"id": 2,
"msrp": 40.0,
"picture": "static/images/products/2",
"product_description": "This is a white wool womens sweater",
"product_name": "Womens Sweater"
},
{
"category_id": [
1,
2,
3,
4
],
"id": 4,
"msrp": 12.0,
"picture": "static/images/products/4",
"product_description": "This is a pair of black holiday unisex socks.",
"product_name": "Holiday Unisex Socks"
},
{
"category_id": [
2,
4
],
"id": 5,
"msrp": 120.0,
"picture": "static/images/products/5",
"product_description": "This is a womens watch in gold.",
"product_name": "Womens Watch"
}
]
}Retrieves specific womens-apparel collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/womens-apparel/2{
"success": true,
"womens_apparel_data": {
"category_id": [
2
],
"id": 2,
"msrp": 40.0,
"picture": "static/images/products/2",
"product_description": "This is a white wool womens sweater",
"product_name": "Womens Sweater"
}
}Retrieves holiday collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/holiday{
"holiday_products_data": [
{
"category_id": [
1,
3
],
"id": 3,
"msrp": 40.0,
"picture": "static/images/products/3",
"product_description": "This is a husky red mens holiday sweater.",
"product_name": "Mens Holiday Sweater"
},
{
"category_id": [
1,
2,
3,
4
],
"id": 4,
"msrp": 12.0,
"picture": "static/images/products/4",
"product_description": "This is a pair of black holiday unisex socks.",
"product_name": "Holiday Unisex Socks"
}
],
"success": true
}Retrieves specific holiday collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/holiday/3{
"holiday_products_data": {
"category_id": [
1,
3
],
"id": 3,
"msrp": 40.0,
"picture": "static/images/products/3",
"product_description": "This is a husky red mens holiday sweater.",
"product_name": "Mens Holiday Sweater"
},
"success": true
}Retrieves miscellaneous collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/misc{
"misc_products_data": [
{
"category_id": [
1,
2,
3,
4
],
"id": 4,
"msrp": 12.0,
"picture": "static/images/products/4",
"product_description": "This is a pair of black holiday unisex socks.",
"product_name": "Holiday Unisex Socks"
},
{
"category_id": [
2,
4
],
"id": 5,
"msrp": 120.0,
"picture": "static/images/products/5",
"product_description": "This is a womens watch in gold.",
"product_name": "Womens Watch"
}
],
"success": true
}Retrieves specific miscellaneous collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/misc/4{
"misc_products_data": {
"category_id": [
1,
2,
3,
4
],
"id": 4,
"msrp": 12.0,
"picture": "static/images/products/4",
"product_description": "This is a pair of black holiday unisex socks.",
"product_name": "Holiday Unisex Socks"
},
"success": true
}Retrieves all products from database:
$ curl -X GET http://127.0.0.1:5000/products{
"products": [
{
"category_id": [
1
],
"id": 1,
"msrp": 25.0,
"picture": "static/images/products/1",
"product_description": "This is a tapered mens summer blue t-shirt.",
"product_name": "Mens Summer Blue Tee"
},
{
"category_id": [
2
],
"id": 2,
"msrp": 40.0,
"picture": "static/images/products/2",
"product_description": "This is a white wool womens sweater",
"product_name": "Womens Sweater"
},
{
"category_id": [
1,
3
],
"id": 3,
"msrp": 40.0,
"picture": "static/images/products/3",
"product_description": "This is a husky red mens holiday sweater.",
"product_name": "Mens Holiday Sweater"
},
{
"category_id": [
1,
2,
3,
4
],
"id": 4,
"msrp": 12.0,
"picture": "static/images/products/4",
"product_description": "This is a pair of black holiday unisex socks.",
"product_name": "Holiday Unisex Socks"
},
{
"category_id": [
2,
4
],
"id": 5,
"msrp": 120.0,
"picture": "static/images/products/5",
"product_description": "This is a womens watch in gold.",
"product_name": "Womens Watch"
}
],
"success": true
}Retrieves specific product from database:
$ curl -X GET http://127.0.0.1:5000/products/2{
"products": {
"category_id": [
2
],
"id": 2,
"msrp": 40.0,
"picture": "static/images/products/2",
"product_description": "This is a white wool womens sweater",
"product_name": "Womens Sweater"
},
"success": true
}Redirects you to the index.html file for the frontend:
$ curl -X GET http://127.0.0.1:5000/This will return the `index.html` file.
- Frontend will be developed further using React.js
- The /search endpoint will be implemented to work with the frontend
- Since the UI and Authentication for the frontend was created using Auth0's Sample Project, a new UI/UX will be designed in the future upon further learning the React.js Framework.
Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Distributed under the Apache 2.0 License. See LICENSE for more information.
Jonathan Gutierrez - jonguti23@outlook.com
Project Link: https://github.com/jonnyg23/flask-rest-ecommerce