Add crud-mysql module: Spring Boot 4.1 CRUD API on a real MySQL 8.4.6 with JPA, Flyway, validation and ProblemDetail errors
Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01HhW8LD8r3EigoBaCGrQZx5 Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01HhW8LD8r3EigoBaCGrQZx5
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
# 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` |
|
||||
Reference in New Issue
Block a user