Monolith-first to microservices with Spring Boot, test-driven development, event-driven systems, common architecture patterns, nonfunctional requirements, and end-to-end testing with Cucumber.
As a user of the application, I want to solve a random multiplication problem using mental calculation so I exercise my brain.
- Create a basic service with business logic.
- Create a basic API to access this service (REST API).
- Create a basic web page to ask the users to solve that calculation.
Generate the project skeleton with Lombok, Spring Web, and Validation: Spring Initializr with Java 8, Gradle, Spring Boot 2.4.5
- Client tier: user interface
- Application tier: business logic, interfaces, and the data interfaces for persistence.
- Data store tier: persists the application's data (e.g. Database, file system, etc.)
The application tier is made up of the following layers:
- Business Layer - Classes that model the domain
- Presentation Layer - Controller classes that implement the REST API
- Data Layer - Persists entities with Data Access Objects (DAO) or Repoistories (Domain)
- Domain Layer - Domain is isolated and independent of everything else
Three stereotype annotations that map to each of layers:
@Controller
- Presentation Layer, used for the REST API@Service
- Business Layer for business logic@Repository
- Data Layer, classes that interact with the Database
When we annotate classes with these variants, they become Spring-managed components.
- When initializing the web context, Spring scans your packages and loads them as beans
- We can use dependency injection to wire (or inject) these beans and use services from our presentation layer (controllers)
Start by modeling the business domain to structure the project:
- Challenge - The math problem
- User - The user
- Challenge Attempt - The attempt by the user to solve the math problem
- Challenge and User are independent
- Challenge Attempts reference a User and a Challenge
- User
- Challenge
microservices.book.multiplication.user.User
microservices.book.multiplication.Challenge
microservices.book.multiplication.challenge.ChallengeAttempt
- Functionality to generate a multiplication problem
- Functionality to check whether an attempt is correct
REpresentational State Transfer (REST) - Uses HTTP verbs to perform API operations:
HTTP Verb | Operation on Collection | Operation on Item |
---|---|---|
GET | Gets full list of items | Get the item |
POST | Creates a new item | Not Applicable |
PUT | Not Applicable | Updates the item |
DELETE | Deletes the full collection | Deletes the item |
REST APIs with Spring Boot use the following annotations:
@RestController
- specialization of @Controller@RequestBody
- Used to pass body of request to method and Spring will deserialize custom class to JSON@RequestMapping
- Model resources and verbs at class and method level and spring provides variants@GetMapping
- Get@PostMapping
- Create@PutMapping
- Update@DeleteMapping
- Delete
- An interface to get a random multiplication problem
- GET
/challenges/random
- GET
- An endpoint to send a guess for a given multiplication problem from a user alias
- POST
/attempts
- POST
- Both resources belong to the challenges domain