Status: Not in development at the moment
Inspired by Realword project from Thinkster, this project is aimed at the same goal:
While most "todo" demos provide an excellent cursory glance at a framework's capabilities, they typically don't convey the knowledge & perspective required to actually build real applications with it.
YAFIG is aimed to build a production-ready Instagram-clone with minimal functionalities. This project will only implement the following features:
- Register & User login
- User can follow or block other users
- Upload, edit and delete a post
- Comment & like posts
- Search the posts
The backend of this project will be implemented in two approaches: microservice & monolithic architecture in Jamstack style.
This project is an initiative for me to learn in public by building a real project from scratch. I am pretty sure I have a lot of things to learn along this journey. This is my greenfield to test new technologies that interest me.
Some parts of this system are not implemented consistently. For example, you will see one module is implemented in MVC architecture and another in Clean architecture. This is intentional because I wanted to learn different approaches to do the same thing. Speed is not my priority in this project. It may takes time for me to understand many of the framework/technology in detail, so I don't mind taking a longer time to understand them in detail.
These resources design is influenced by Microsoft API Design guidance
Resource | POST | GET | PUT | DELETE |
---|---|---|---|---|
/users | Authenticate user based on Header Authorization supplied | |||
/users/register | Create a new user. This will send an welcome email to the new user. | |||
/users/login | Login the user and return a JWT token | |||
/users/{username} | Get user details | Update user | Delete user | |
/users/{username}/posts/ | Get user's posts | |||
/users/follow/{username} | Creates a new record in relationship table and update follow_count of that user |
|||
/users/block/{username} | Creates a new record in relationship table and remove blocked user posts from timeline table |
/users
is mainly for the frontend website to authorize the current user context- Follow and block operations will generate a materialized views in the database in the database to save the compute power during query. It will be executed in a single database transaction.
The operations exposed via HTTP REST are:
Resource | POST | GET | PUT | DELETE |
---|---|---|---|---|
/posts/ | Upload a new post | Get user's posts | ||
/posts/timeline/ | Get user's timeline | |||
/posts/{id}/ | Get post | Update post | Delete post | |
/posts/user/{user_id}/ | Get posts by user |
- After posting a new picture, it will generate a thumbnail and index the new post in Elasticsearch
- Deleting a post will delete the post's comment
The HTTP REST operations are:
Resource | POST | GET | PUT | DELETE |
---|---|---|---|---|
/posts/{post_id}/comments/ | Create a new comment | Get post's comments | ||
/posts/{post_id}/comments/{comment_id}/ | Get a comment | Edit post comment | Delete comment |
Search will be based on:
- tags
- description
- user
Search service is exposed via HTTP REST. The HTTP REST operation is:
-
GET
/search/query?query={query}&limit={limit}&offset={offset}
Search for posts with
limit
andoffset
parameters are for the search result pagination. -
GET
/search/autocomplete?query={query}
This is for the search form to display autocomplete suggestions in the frontend
The page will have the following paths:
- Main page at
/
path - Login page at
/login
path - Register page at
/register
path - Feed page at
/feed
path - Post CRUD pages at
/p/{id}
path - User CRUD pages at
/u/{id}
path - Profile page at
/u/{own id}
path - Search page at
/search
path - Upload page at
/upload
path
Frontend specs:
- Jamstack approach where each operation on the site will perform API requests to the API endpoints
- The frontend must be able to be served from CDN and/or Object Storage.
The frontend is implemented in:
Other frameworks that I might be interested to explore next would be Svelte and NextJS.
The API Servers will be implemented in two approaches: Monolithic and Microservice. Both of them are doing essentially the same thing, but in a different manner.
- Python using Django REST Framework (DRF).
Development approaches for each resource:
Django App | Details |
---|---|
API Doc | Uses DRF YASG to generate API Doc |
User | Written in DRF function-based views & SimpleJWT library for authentication. |
Post | Written in Generic Views |
Search | Written in class-based views |
External services used:
- PostgreSQL
- Celery
- Redis
- Elasticsearch
- Use CircleCI for CI/CD automation
- Docker for containerization
- Setup minimal S3 permission with this policy permission.
- VM is hosted in Hetzner Germany region
- Celery & Celery Beatx
- Reliability: on_commit() message dispatching, atomic transaction
- Performance optimizations: Select_Related, Prefetch_related, defer & only query, query annotation, Func
- Queryset Q & F
- FilterSet
- Django-cacheops
- Django social login
- Django Channel & Shared WebWorker
- django-debug-toolbar & django-silk
- uptime monitoring
- APM
- django-url-filter
- Varnish caching (serving static cache even the API is breaking)
- Rate limiting
- Load testing with Locust
- django-memoize
- ORM: unique_together, indexes & partial/conditional index, Lag, Window, raw SQL, select extra, custom queryset and custom manager, inspect query (
str(order.query
)
- Build user registration & authorization using SimpleJWT, Github repo
- JWT Auth with DjangoREST API
- Django REST OpenAPI 3 Support
- Build File/Image upload in DRF
- Upload files to S3 using DRF
- Soft Deletion in Django
- Building a Full-Text Search App Using Django, Docker and Elasticsearch
- Build Elasticsearch autocomplete feature for Django app
- Build Elasticsearch with Django
NuxtJS / Vuejs