Files

69 lines
3.4 KiB
Markdown

# crud-mysql
Companion project for the article **[Spring Boot CRUD REST API with MySQL and Spring Data JPA](https://ankurm.com/spring-boot-crud-rest-api-mysql/)** on **[ankurm.com](https://ankurm.com)**.
A complete Create / Read / Update / Delete API for books on **Spring Boot 4.1, Spring Data JPA (Hibernate),
Flyway and MySQL 8.4**, with Bean Validation and RFC 9457 `ProblemDetail` errors. Every console block
quoted in the article came out of `output/`, written by the test suite against a real MySQL server, so a
claim that stops being true turns the build red.
There is deliberately **no `docs/` folder**: the deeper material lives in collapsible sections inside the
article itself.
## Versions
| | |
|---|---|
| Spring Boot | 4.1.1 |
| Spring Framework | 7.0.9 |
| MySQL server used for `output/` | MySQL Community Server 8.4.6 (official Linux tarball, started directly; **not** Docker) |
| MySQL driver | MySQL Connector/J 9.7.0 (what Boot 4.1.1 manages) |
| JDK | 21 (OpenJDK 21.0.12) |
| Maven | 3.9 |
Only JDK 21 was used. `docker-compose.yml` was **not run** (the sandbox had no Docker).
## Quickstart
```bash
docker compose up -d # or run scripts/mysql-setup.sql against a MySQL you already have
mvn test # runs the scenarios and rewrites output/01-04
mvn spring-boot:run # API on http://localhost:8080/api/books
```
Defaults: `jdbc:mysql://localhost:3306/library`, user `library`, password `library`. Override with
`DB_URL`, `DB_USER` and `DB_PASSWORD`. The tests start the real application and delete all rows in the
`book` table first, so point them at a database you can wipe.
## Endpoints
| Method and path | What it does | Success | Errors |
|---|---|---|---|
| `POST /api/books` | create | `201` + `Location` | `400` validation, `409` duplicate ISBN |
| `GET /api/books/{id}` | read one | `200` | `404`, `400` (id not a number) |
| `GET /api/books?author=&page=&size=` | list, paged, optional author filter | `200` | |
| `PUT /api/books/{id}` | replace | `200` | `400`, `404`, `409` |
| `DELETE /api/books/{id}` | delete | `204` | `404` |
## Source layout
| Path | What it is |
|---|---|
| `book/Book.java` | the JPA entity, mapped to the `book` table |
| `book/BookRepository.java` | a Spring Data interface: no implementation to write |
| `book/BookService.java` | transactions, paging, dirty checking for the update |
| `book/BookController.java` | the HTTP layer |
| `book/BookRequest.java`, `BookResponse.java`, `PageResponse.java` | what crosses the wire |
| `error/ApiExceptionHandler.java` | every error becomes a `ProblemDetail` |
| `resources/db/migration/V1__create_book.sql` | the schema, owned by Flyway |
## Captured output
| File | What it shows |
|---|---|
| `01-mysql-and-schema.txt` | the server and driver versions, the Hibernate dialect, the Flyway history and `SHOW CREATE TABLE` |
| `02-crud-walkthrough.txt` | create, read, list (paged and filtered), update, delete: the requests are made with the JDK's `HttpClient` and printed as the equivalent curl commands, with the real responses |
| `03-error-responses.txt` | validation, duplicate ISBN on create and on update, the message MySQL itself returned, 404, bad id, bad JSON |
| `04-sql-per-request.txt` | the SQL Hibernate sent for each kind of request |
| `05-real-curl.txt` | real `curl -i` against the packaged jar (headers included), written by `scripts/curl-demo.sh` |