DEV Community

Cover image for An E-commerce API
Hana Belay
Hana Belay

Posted on

An E-commerce API

One of my most recent projects is an E-commerce API that has helped me solidify more advanced concepts in Django and Django Rest Framework. I learned to work in a dockerized environment and use Nginx, Gunicorn ... inside Docker to make my application production ready.

Basic Functionalities

  • Registration using either phone number or email
  • Basic E-commerce features.
  • Payment integration using Stripe.
  • Caching using a Redis backend.
  • Sending emails asynchronously using Celery and Redis as a message broker.
  • Custom permissions set for necessary endpoints.
  • Documentation using DRF Spectacular
  • Dockerized for local development and production

Technologies Used

  • Django Rest Framework
  • PostgreSQL
  • Celery
  • Redis
  • Nginx
  • Docker
  • Stripe

This project makes use of:

  • Viewsets
  • Custom permissions
  • Nested serializers and so on. If you would like to strengthen your skills, I highly recommend you to check it out

I used Docker for local development and it has been so great! And then, with some adjustments, the application is production ready.

Tip: you can export your database schema to a SQL file using the command below:

docker exec -i [container_id] pg_dump -U [postgres_user]  --schema-only [database_name] > [target_path]
Enter fullscreen mode Exit fullscreen mode

And then use this tool https://dbdiagram.io/ to generate ER diagram while playing around with the SQL code.

ER Diagram

Link to GitHub repo: https://github.com/earthcomfy/django-ecommerce-api

I welcome any suggestion. Follow me to get upcoming tutorials.

Top comments (6)

Collapse
 
aarone4 profile image
Aaron Reese

Good start. Looking at you ERD you are storing price on the product but not on the order line. This means that if you ever update the price on any products you cannot calculate the value of the order. Order line needs to have the unit price as a minimum requirement and product price needs to be in a separate table that can be time-stamped so you know which price is effective at the order/charge/ship date.
There are lots of other issues but this one is likely to bite you very quickly.

Collapse
 
earthcomfy profile image
Hana Belay • Edited

Hi, thanks for your feedback.

OrderItem is related with product and I have a property inside it that calculates the total price:

@cached_property
def cost(self):
    """
    Total cost of the ordered item
    """
    return round(self.quantity * self.product.price, 2)
Enter fullscreen mode Exit fullscreen mode

So this cost property is updated whenver a user makes an order.

Collapse
 
aarone4 profile image
Aaron Reese

and that is exactly the problem. Next year when you change your price, what was the value of the order placed today?

Minimum viable soution:

Product_price
----------------
ID INT IDENTITY(1,1),
Product_id (FK to product_product.ID)
EffectiveDate DATE,
Price CURRENCY.
Enter fullscreen mode Exit fullscreen mode

It gets more complicated if you have different currencies, pricing strategies, customer banding, bulk discounts, special offers etc. but at the very least you need a time-series table for prices over time.

Thread Thread
 
earthcomfy profile image
Hana Belay

Ah, I see your point thanks!

Thread Thread
 
aarone4 profile image
Aaron Reese

This is an internal implementation detail; it doesn't need to change your API returned data struture unless it is important to the front end to know how the price was derived.

You will also likely need to understand WHEN the order price becomes fixed. It is at point the order is sumitted, when it is approved, when stock is allocated, when it is charged or when it is shipped, or something else.

I have worked with at least half a dozen ecommerce platforms that got the cost of sale wrong because they allocated it at the time the order was placed, not when the order was shipped and the cost-basis for the stock had changed in the meantime.
For example. I have one unit in stock which cost me $10. I sold it for $22 so my 'profit' is $12. I order another unit and it costs me $12 so my average cost is £11. (10+12 / 2). I ship my first order. I take $10 (Cost of sales) from stock (balance sheet) and put it to Cost of Goods Sold (P&L). My accounts say Stock = $12 but my stock control system says 1 unit @ $11 - WTF?

As you can see, what looks like a simple system is actually extrememely complicated.
I worked with one ecommerce company that had 10 different ways to price an order and operated in 6 intermational markets. I had to maintain 10.4M prices over 60,000 SKUs with a bulk price review twice a year and ad-hoc adjustments almost every day.

Thread Thread
 
earthcomfy profile image
Hana Belay

Right, thanks for sharing your experience. It is indeed important to make sure an app works as intended by analyzing different scenarios 💯