This project is a Django-based REST API designed to handle order creation with fault tolerance and idempotency. It simulates a 10% failure rate, supports asynchronous logging, and ensures duplicate orders are processed efficiently using a unique hash_key.
The application features a single endpoint (/orders/) that accepts POST requests with items (a list of strings) and payment_amount (a positive decimal). Key functionalities include:
- Idempotent order processing with a
200 OKresponse for duplicates. - A 10% random failure simulation returning
503 Service Unavailablewith a 5-second retry header. - Asynchronous logging of order attempts.
- Validation for non-empty
itemsand positivepayment_amount.
- Docker & Docker Compose
- Python 3.11 , Django==5.2.7 and PostgreSQL 16 for local run ( Was the tested during implementation)
-
Clone the Repository
git clone https://github.com/tbwahacker/order_processor.git cd order_processor -
Configure Environment Ensure
.envis present with the following variables:DB_NAME=orderprocessordbDB_USER=your-userDB_PASSWORD=your-passwordDB_HOST=dbDB_PORT=5432DEBUG=TrueSECRET_KEY=your-secret-key-hereALLOWED_HOSTS=localhost,127.0.0.1CORS_ALLOWED_ORIGINS=http://127.0.0.1:8080,http://localhost:8080
-
Build and Start Containers Use Docker Compose with the
.envfile:docker-compose up --build
-
Apply Migrations Initialize the database:
docker-compose exec app python manage.py makemigrations docker-compose exec app python manage.py migrate
-
./logs/orders.logis host-mounted so/app/logs/orders.logis accessible outside container.
-
-
Run Tests Execute the test suite:
docker-compose exec app python manage.py test
-
Documentation
- Swagger UI via
drf_yasgat/swagger/. - Postman test script (to check either success or retry):
pm.test("Has valid response", function () {
var json = pm.response.json();
pm.expect(pm.response.code === 201 || pm.response.code === 200 || pm.response.code === 503).to.be.true;
if (pm.response.code === 503) {
pm.expect(pm.response.headers.has('Retry-After')).to.be.true;
} else {
pm.expect(json).to.have.property("order_id");
}
});- Postman collection tests results included at
docs/OrderProcessor.postman_collection.json. - To view and test all API endpoints easily:
- Open Postman.
- Click File → Import.
- Select the file docs/OrderProcessor.postman_collection.json.
- Postman will display all available API requests with prefilled data.
- Click Send to test each endpoint — no manual setup needed.
- Access the API
Test the endpoint at
http://localhost:8000/orders/:curl -X POST http://localhost:8000/orders/ -H "Content-Type: application/json" -d '{"items": ["item1", "item2"], "payment_amount": 100.50}'
-
Configure Environment Update
.envfor production:DB_NAME=orderprocessordbDB_USER=your-userDB_PASSWORD=your-passwordDB_HOST=dbDB_PORT=5432DEBUG=FalseSECRET_KEY=your-production-secret-key-hereALLOWED_HOSTS=yourdomain.comCORS_ALLOWED_ORIGINS=your-front-end-domains-separated-in-commas-if-many
-
Build Production Containers Build with a production configuration:
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up --build
-
Apply Migrations Run migrations in production:
docker-compose -f docker-compose.prod.yml exec app python manage.py migrate -
Set Up Gunicorn Configure Gunicorn as the WSGI server:
docker-compose -f docker-compose.prod.yml exec app gunicorn --bind 0.0.0.0:8000 order_processor.wsgi:application -
Configure Nginx (Optional) Set up Nginx as a reverse proxy:
server { listen 80; server_name yourdomain.com; location / { proxy_pass http://localhost:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
-
Deploy Deploy using your preferred method (e.g., Docker Swarm or a cloud provider).
- The
OrderCreateViewhandles idempotency by checkinghash_keybefore creation and includes anIntegrityErrorfallback for race conditions. - Ensure
.env.dockeris properly configured with your database credentials and host settings. - PostgreSQL is required in production for
IntegrityErrorhandling to function correctly. - Use DEBUG=False and set proper ALLOWED_HOSTS and CORS_ALLOWED_ORIGINS in production
- I added Token-based authentication and CORS setups as optional enhancements as per test challenge said
- Windows Wsl, git bash or any Linux//Unix bash will work really well with Curl tool provided in endpoint test above, unless if using windows powershell use:
or use Curl.exe with separated string parameters
Invoke-WebRequest -Uri http://localhost:8000/orders/ -Method POST -Body '{"items": ["item1", "item2"], "payment_amount": 100.50}' -ContentType "application/json"
- Docker provides a consistent environment across development, testing, and production. It packages the Django app, PostgreSQL database, and dependencies in reproducible containers, simplifying setup, scaling, and CI/CD deployment. While Python virtual environments handle dependencies, Docker ensures system-level reproducibility and faster onboarding for any developer or server.