A Spring Boot application that consumes the quote-service REST API.
Based on Spring Guide: Consuming a RESTful Web Service.
03-spring-consuming-rest/
├── pom.xml
├── src/main/java/com/example/consumingrest/
│ ├── ConsumingRestApplication.java # Main entry point
│ ├── QuoteController.java # REST endpoint, calls quote-service
│ ├── Quote.java # Record for JSON response
│ └── Value.java # Record for nested JSON object
├── src/main/resources/
│ └── application.properties # Port config (8081) + quote-service URL
├── src/test/java/com/example/consumingrest/
│ ├── ConsumingRestApplicationTests.java # Spring context test
│ └── QuoteControllerTest.java # Endpoint tests with mocked backend
└── docs/
├── DEVELOPER_NOTES.md # My developer notes
├── images/ # Screenshots
├── setup/
│ ├── spring-initializr.md # Project setup from start.spring.io
│ └── run-instructions.md # Detailed run steps
├── concepts/
│ ├── quote-controller.md # Explains RestClient and the controller
│ └── java-records.md # Explains records and JSON mapping
├── reference/
│ └── guide.md # Original Spring guide
└── adr/
├── ADR-0001-use-restclient.md # Why RestClient
├── ADR-0002-expose-quote-endpoint.md # Why REST endpoint
├── ADR-0003-error-handling-fallback.md # Why graceful error handling
└── ADR-0004-externalize-base-url.md # Why configurable URL
This consumer exposes a /quote endpoint that fetches a random quote from the quote-service:
sequenceDiagram
actor User
participant Consumer as Consumer (localhost:8081)
participant Provider as Quote Service (localhost:8080)
User->>Consumer: GET /quote
Consumer->>Provider: GET /api/random
Provider-->>Consumer: JSON (Quote)
Consumer-->>User: JSON (Quote)
Step 1: Start the quote-service first (in a separate terminal):
cd ../03-quote-service
./mvnw spring-boot:runStep 2: Start this consumer:
./mvnw spring-boot:runStep 3: Fetch a quote:
curl http://localhost:8081/quote{
"type": "success",
"value": {
"id": 3,
"quote": "Spring Boot is the best thing that has happened to Java development in a long time."
}
}| Service | Port |
|---|---|
| quote-service | 8080 |
| consuming-rest | 8081 |
(Port 8081 is set in this module's application.properties via server.port=8081.)
- RestClient - Spring Boot 3.2+ HTTP client for making REST calls.
- Java Records - Immutable data classes (
Quote,Value). - Constructor Injection - How Spring provides dependencies.
- @Value - Inject configuration from
application.properties. - Error Handling - Graceful fallback when backend is unavailable.
- @JsonIgnoreProperties - Ignore unknown JSON fields during deserialization.
| File | Explains |
|---|---|
| DEVELOPER_NOTES.md | My developer notes |
| setup/spring-initializr.md | Project setup from start.spring.io |
| setup/run-instructions.md | Detailed run steps |
| concepts/quote-controller.md | How RestClient and the controller work |
| concepts/java-records.md | What records are and how JSON mapping works |
| reference/guide.md | Original Spring guide |
| ADR | Decision |
|---|---|
| ADR-0001 | Why RestClient instead of RestTemplate |
| ADR-0002 | Why a REST endpoint instead of ApplicationRunner |
| ADR-0003 | Why graceful error handling with fallback |
| ADR-0004 | Why externalize the quote-service URL |
This consumer expects responses from 03-quote-service in the following format:
{
"type": "success",
"value": { "id": 1, "quote": "..." }
}When the quote-service is unavailable, this consumer returns a fallback response:
{
"type": "error",
"value": { "id": -1, "quote": "Quote service unavailable" }
}See ADR-0003 for the design rationale.
- 03-quote-service - The backend this consumer calls
- Spring Guide: Consuming a RESTful Web Service
- Spring Docs: REST Clients
