---
title: Create the Spring Boot project
linkTitle: Create the project
description: Set up a Spring Boot project with an external REST API integration using WireMock and Testcontainers.
weight: 10
---
## Set up the project
Create a Spring Boot project from [Spring Initializr](https://start.spring.io)
by selecting the **Spring Web** and **Testcontainers** starters.
Alternatively, clone the
[guide repository](https://github.com/testcontainers/tc-guide-testing-rest-api-integrations-using-wiremock).
After generating the project, add the **REST Assured**, **WireMock**, and
**WireMock Testcontainers module** libraries as test dependencies. The key
dependencies in `pom.xml` are:
```xml
17
2.0.4
1.0-alpha-13
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.testcontainers
testcontainers-junit-jupiter
test
org.wiremock
wiremock-standalone
3.6.0
test
org.wiremock.integrations.testcontainers
wiremock-testcontainers-module
${wiremock-testcontainers.version}
test
io.rest-assured
rest-assured
test
```
Using the Testcontainers BOM (Bill of Materials) is recommended so that you
don't have to repeat the version for every Testcontainers module dependency.
This guide builds an application that manages video albums. A third-party REST
API handles photo assets. For demonstration purposes, the application uses the
publicly available [JSONPlaceholder](https://jsonplaceholder.typicode.com/) API
as a photo service.
The application exposes a `GET /api/albums/{albumId}` endpoint that calls the
photo service to fetch photos for a given album.
[WireMock](https://wiremock.org/) is a tool for building mock APIs.
Testcontainers provides a
[WireMock module](https://testcontainers.com/modules/wiremock/) that runs
WireMock as a Docker container.
## Create the Album and Photo models
Create `Album.java` using Java records:
```java
package com.testcontainers.demo;
import java.util.List;
public record Album(Long albumId, List photos) {}
record Photo(Long id, String title, String url, String thumbnailUrl) {}
```
## Create the PhotoServiceClient
Create `PhotoServiceClient.java`, which uses `RestTemplate` to fetch photos for
a given album ID:
```java
package com.testcontainers.demo;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
class PhotoServiceClient {
private final String baseUrl;
private final RestTemplate restTemplate;
PhotoServiceClient(
@Value("${photos.api.base-url}") String baseUrl,
RestTemplateBuilder builder
) {
this.baseUrl = baseUrl;
this.restTemplate = builder.build();
}
List getPhotos(Long albumId) {
String url = baseUrl + "/albums/{albumId}/photos";
ResponseEntity> response = restTemplate.exchange(
url,
HttpMethod.GET,
null,
new ParameterizedTypeReference<>() {},
albumId
);
return response.getBody();
}
}
```
The photo service base URL is externalized as a configuration property. Add the
following entry to `src/main/resources/application.properties`:
```properties
photos.api.base-url=https://jsonplaceholder.typicode.com
```
## Create the REST API endpoint
Create `AlbumController.java`:
```java
package com.testcontainers.demo;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestClientResponseException;
@RestController
@RequestMapping("/api")
class AlbumController {
private static final Logger logger = LoggerFactory.getLogger(
AlbumController.class
);
private final PhotoServiceClient photoServiceClient;
AlbumController(PhotoServiceClient photoServiceClient) {
this.photoServiceClient = photoServiceClient;
}
@GetMapping("/albums/{albumId}")
public ResponseEntity getAlbumById(@PathVariable Long albumId) {
try {
List photos = photoServiceClient.getPhotos(albumId);
return ResponseEntity.ok(new Album(albumId, photos));
} catch (RestClientResponseException e) {
logger.error("Failed to get photos", e);
return new ResponseEntity<>(e.getStatusCode());
}
}
}
```
This endpoint calls the photo service for a given album ID and returns a
response like:
```json
{
"albumId": 1,
"photos": [
{
"id": 51,
"title": "non sunt voluptatem placeat consequuntur rem incidunt",
"url": "https://via.placeholder.com/600/8e973b",
"thumbnailUrl": "https://via.placeholder.com/150/8e973b"
},
{
"id": 52,
"title": "eveniet pariatur quia nobis reiciendis laboriosam ea",
"url": "https://via.placeholder.com/600/121fa4",
"thumbnailUrl": "https://via.placeholder.com/150/121fa4"
}
]
}
```