Taco Cloud by Craig Walls, Spring in Action 6th edition. During the course of this book an author creates a complete web application named Taco Cloud. However, I decided to create an application with similar functionalities, but with focus on the REST architecture. Not long ago acquired this book, so more new functionalities are on the way.
A Taco Cloud is RESTful backend API for a taco ordering, built with Spring Boot 3.4.5. Users can browse ingredients, build custom tacos, place orders, and manage their accounts — all secured with JWT authentication.
- User registration and login with JWT-based authentication
- Role-based access control (
USER,DEVELOPER) - CRUD operations for Ingredients, Tacos, and Orders
- Order lifecycle tracking with statuses (e.g.
PREPARING) - Soft-delete support across all major entities
- Database migrations managed by Liquibase
- Pre-loaded seed data for quick local testing
| Layer | Technology |
|---|---|
| Framework | Spring Boot 3.4.5 |
| Language | Java |
| Security | Spring Security 6 + JJWT 0.12.5 |
| Persistence | Spring Data JPA + Hibernate |
| Database | MySQL 9 |
| Migrations | Liquibase 4.29.2 |
| Mapping | MapStruct 1.6.3 |
| Validation | Jakarta Validation 3 |
| Build | Maven |
- Java 17+
- MySQL 8+ running locally (or via Docker)
- Maven 3.8+
Create a .env file in the project root (the app loads it automatically via spring.config.import):
DATABASE_URL=jdbc:mysql://localhost:3306/taco_cloud
MYSQL_USER=your_db_user
MYSQL_PASSWORD=your_db_password
JWT_SECRET=your_super_secret_key_at_least_256_bits
JWT_EXPIRATION=86400000CREATE DATABASE taco_cloud;# Using Maven
mvn spring-boot:run
# Or using the pre-built JAR
java -jar taco-cloud-0_0_1-SNAPSHOT.jarLiquibase will automatically run all migrations on startup, including creating tables and seeding test data.
http://localhost:8080/taco_cloud_api
All endpoints except /auth/** require a valid JWT token in the Authorization header:
Authorization: Bearer <your_token>
| Password | Role | |
|---|---|---|
bob@mail |
password |
USER |
[email protected] |
password |
USER, DEVELOPER |
Note: Passwords in the database are BCrypt-hashed. The seed password shown above is a placeholder — update the DB seed data with your actual test password.
| Method | Path | Description | Auth Required |
|---|---|---|---|
| POST | /auth/register |
Register a new user | No |
| POST | /auth/login |
Login and receive a JWT token | No |
| Method | Path | Description |
|---|---|---|
| GET | /ingredient |
List all ingredients |
| GET | /ingredient/{id} |
Get ingredient by ID |
| POST | /ingredient |
Create a new ingredient |
| PUT | /ingredient/{id} |
Update an ingredient |
| DELETE | /ingredient/{id} |
Delete an ingredient |
| Method | Path | Description |
|---|---|---|
| GET | /taco |
List all tacos |
| GET | /taco/{id} |
Get taco by ID |
| POST | /taco |
Create a new taco |
| PUT | /taco/{id} |
Update a taco |
| DELETE | /taco/{id} |
Delete a taco |
| Method | Path | Description |
|---|---|---|
| GET | /order |
Get all orders for the authenticated user |
| GET | /order/{id} |
Get order by ID |
| POST | /order |
Place a new order |
| PUT | /order/{id} |
Update an order |
| DELETE | /order/{id} |
Cancel/delete an order |
Key tables:
users— stores account info (name, email, address, phone)roles—USERandDEVELOPERrolesuser_role— many-to-many join between users and rolesingredients— individual taco ingredientstacos— custom taco creations, linked to ingredientsorders— customer orders with delivery info and payment details, linked to tacos viaorder_taco
src/
└── main/
└── java/ihromovyi/tacocloud/
├── controller/ # REST controllers (Auth, Ingredient, Taco, TacoOrder)
├── service/ # Business logic layer
├── repository/ # Spring Data JPA repositories
├── model/ # JPA entities (User, Role, Taco, TacoOrder, ...)
├── dto/ # Request/Response DTOs
├── mapper/ # MapStruct mappers
├── security/ # JWT filter, AuthenticationService, UserDetailsService
├── config/ # SecurityConfig, WebConfig, MapperConfig
├── exception/ # Custom exceptions
└── validation/ # Custom validators (e.g. password)
└── resources/
├── application.properties
├── templates/home.html
├── static/pictures/
└── db/changelog/ # Liquibase migration files
User has to write a password with at least 1 capital letter, 1 lowercase letter and a special sign, else receives a BAD_REQUEST.

Successful login with JWT token received.

If you have any interesting suggestion on how to make the application more interesting you are welcome to make pull request.



