Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

PHPintermediatebackendAI generated

Book Lending API

Build a REST API in PHP for a small library. It manages books, members and loans, and answers questions like which books are overdue right now. Clients can add books, register members, lend a book (only if a copy is available), return it, and list overdue loans. All input is validated, and errors come back as clear JSON with the right HTTP status codes. You'll use Composer for dependencies and autoloading, PDO with prepared statements for PostgreSQL, SQL with joins and date calculations, and a clean structure of routing, validation and data access without a large framework.

Estimate
~14h
Steps
7
Completed by
0
Proposed by
codeseed.app

Composer · PostgreSQL

Project roadmap

  1. 01

    Set up the project

    ~1.5h

    Run composer init and set up PSR-4 autoloading for src/ under the App namespace. Add nikic/fast-route for routing, vlucas/phpdotenv for configuration, and phpunit/phpunit as a dev dependency. Create public/index.php as the single entry point, reading database settings from .env (commit a .env.example, never the real .env). Done when: php -S localhost:8000 -t public serves GET /health, which returns {"status":"ok"}.

  2. 02

    Create the database schema

    ~2h

    Write migrations/001_schema.sql with three tables: books (id, unique isbn, title, author, total_copies), members (id, name, unique email, created_at) and loans (id, book_id, member_id, loaned_at, due_at, and a nullable returned_at), with foreign keys and a check that total_copies is at least 1. Add a script that runs the SQL and inserts a few books and members. Done when: the schema and sample data load into PostgreSQL with one command.

  3. 03

    Books and members endpoints

    ~2.5h

    Implement GET /books (with an ?author= filter), GET /books/{id}, POST /books, POST /members and GET /members/{id}, using only PDO prepared statements. Put validation in its own class: required fields, an ISBN of 10 or 13 digits, a valid email, positive copy counts. Return 201 for created records, 404 when not found, 409 for a duplicate ISBN or email, and 422 with field errors for invalid input. Done when: each endpoint works with curl and returns these codes.

  4. 04

    Lend and return books

    ~2.5h

    Implement POST /loans (book_id, member_id and an optional loan period in days, default 14) and POST /loans/{id}/return. A book can only be lent if it has available copies: total_copies minus its loans that aren't returned. Lock the book row with SELECT ... FOR UPDATE and do the check and insert in one transaction, so two requests can't lend the last copy twice. Returning a loan twice gives 409. Done when: lending the last copy works once and the next attempt is refused.

  5. 05

    Overdue and history queries

    ~2h

    Add GET /loans/overdue, listing loans that are not returned and past due_at, with the book title, member name and days overdue, most overdue first. Add GET /members/{id}/loans with a member's loans, current ones first. Use SQL joins and calculate days overdue in SQL. Done when: with sample loans that are past due, both endpoints return the correct rows.

  6. 06

    Consistent errors and documentation

    ~1.5h

    Add one error handler in index.php so every error returns JSON like {"error":"..."} with the correct status code, and unexpected exceptions return 500 without exposing SQL or stack traces. Log unexpected errors to a file. Document every endpoint in the README with an example request and response. Done when: a failing query returns a clean 500 response and the error is written to the log file.

  7. 07

    Write tests

    ~2h

    Write PHPUnit tests for the validation class and the lending rules: lending when copies are available, refusing when none are left, returning a loan, returning it twice, and calculating days overdue. Run the database tests against a separate test database, never the development one. Done when: vendor/bin/phpunit passes.

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~14h · 7 steps

Tech stack

ComposerPostgreSQL