Skip to content

brandaogabriel7/books-api

Repository files navigation

Books API

A RESTful API for managing books with automatic data enrichment via the Open Library API. Built with Django, PostgreSQL, and Redis — following clean architecture with domain-driven design.

Features

  • CRUD operations for books with filtering, search, and pagination
  • ISBN-based data enrichment — automatically fetches title, authors, publishers, page count, and description from the Open Library API
  • Redis caching — decorator-based cache layer with 2-hour TTL to minimize external API calls
  • Production-ready Docker — multi-stage builds, separate dev/prod configs, health checks via dockerize
  • CI/CD — GitHub Actions pipeline with full integration tests

Tech Stack

Layer Technology
Framework Django 5, Django REST Framework
Database PostgreSQL 13
Cache Redis 5
Testing Pytest (22 test files)
CI/CD GitHub Actions
Containerization Docker, Docker Compose

Architecture

The project follows clean architecture with dependency inversion:

┌─────────────────────────────────────────┐
│         API Views (REST endpoints)      │
│         Filters, Pagination             │
└────────────────┬────────────────────────┘
                 │
┌────────────────▼────────────────────────┐
│       Application Services              │
│  BookService (enrichment orchestration) │
└────────────────┬────────────────────────┘
                 │
┌────────────────▼────────────────────────┐
│         Domain Layer                    │
│  Book Entity, Value Objects (ISBN10,    │
│  ISBN13, PublishDate), Factory,         │
│  Repository Interface                  │
└────────────────┬────────────────────────┘
                 │
┌────────────────▼────────────────────────┐
│       Infrastructure                    │
│  DjangoBookRepository, Redis Cache,     │
│  OpenLibraryClient                      │
└─────────────────────────────────────────┘
books/
├── domain/                # Business logic (no framework dependencies)
│   ├── entity/           # Book entity with behavior
│   ├── value_object/     # ISBN10, ISBN13, PublishDate (validated, immutable)
│   ├── repository/       # Abstract repository interface
│   └── factory/          # Entity construction
├── application/
│   ├── api/              # REST views + tests
│   └── service/          # Enrichment service
└── infrastructure/
    ├── models/           # Django ORM + model mapper
    ├── repository/       # Repository implementation
    ├── cache/            # Redis cache decorator
    └── open_library/     # External API client

Design Patterns

Pattern Where Why
Repository domain/repository/infrastructure/repository/ Abstracts persistence; domain doesn't know about Django ORM
Value Objects domain/value_object/ ISBN10 validates length=10, PublishDate prevents future dates — invalid states are unrepresentable
Factory domain/factory/ Centralizes entity construction with UUID generation and value object creation
Decorator infrastructure/cache/ @redis_cache(prefix, ttl) — transparent caching on any method
Service Layer application/service/ Orchestrates the two-step enrichment flow (book info → work description)

Data Enrichment Flow

Book Create/Update
    │
    ├─ Has ISBN? ──No──→ Skip enrichment
    │
    └─ Yes
        │
        ├─ 1. Fetch book info (title, authors, publishers, pages, publish date)
        │      GET /api/volumes/brief/isbn/{isbn}.json  [cached 2h]
        │
        └─ 2. Fetch description via work key
               GET /{workKey}.json  [cached 2h]
               │
               └─→ Merge enriched data into Book entity

Each step is independently cached and fails gracefully — partial enrichment is returned if the description call fails.

Setup

Prerequisites

Quick Start

make up          # Start Django + PostgreSQL + Redis
make seed-db     # Seed database with sample books
# API available at http://localhost:8000

Production

make up-prod     # Multi-stage Docker build, optimized image, no volume mounts

API

A Postman collection is included with all endpoints.

Endpoints:

  • GET /books/ — List books (supports filtering by title, ISBN, author, publisher + pagination)
  • GET /books/{id}/ — Get book details
  • POST /books/ — Create book (triggers enrichment if ISBN provided)
  • PUT /books/{id}/ — Update book
  • DELETE /books/{id}/ — Delete book

Tests

22 test files covering domain, service, API, repository, and cache layers:

make test
  • Domain tests — entity validation, value object constraints
  • Service tests — enrichment workflow with mocked external API
  • API tests — CRUD operations, filtering, pagination
  • Repository tests — query building, model mapping
  • Cache tests — Redis integration, TTL behavior

Useful Commands

Command Description
make up Start development environment
make up-prod Start production environment
make test Run all tests
make migrate Run Django migrations
make format Format code with black
make logs Show all service logs
make shell-web Django container shell
make shell-db PostgreSQL container shell
make down Stop all services
make clean Stop services + remove volumes

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors