Pollito's Opinion on Spring Boot Development 4: feignClient interfaces
Posted on October 2, 2024 • 4 minutes • 647 words • Other languages: Español
- Some context
- 1. More dependencies
- 2. Write an OAS yaml file
- 3. Generate the interfaces.
- Next lecture
Some context
This is the fourth part of the Spring Boot Development blog series.
- The objective of the series is to be a demonstration of how to consume and create an API following Design by Contract principles .
- To achieve that, we are creating a Java Spring Boot Microservice that handles information about users.
- You can find the code of the final result at this GitHub repo - branch feature/feignClient .
- Here’s a diagram of its components. For a deep explanation visit Understanding the project
So far we created:
- LogFilter.
- GlobalControllerAdvice.
- UsersController.
In this blog we are going to create the UsersApi. Let’s start!
1. More dependencies
These are:
- Jakarta Annotations API
- Spring Cloud Starter OpenFeign
- Feign OkHttp
- Feign Jackson
- Feign Gson
- JUnit Jupiter API
Here I leave some ready copy-paste for you. Consider double-checking the latest version.
Under the <dependencies> tag:
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>4.1.3</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<version>13.4</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
<version>13.4</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-gson</artifactId>
<version>13.4</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.11.1</version>
</dependency>
2. Write an OAS yaml file
Sometimes you’ll get lucky and find that the REST endpoint you want to consume already has an available OAS. But in case it doesn’t, you’ll have to write a representation of what to expect from it.
For this scenario, I’m going to be using the /users from {JSON} Placeholder to get fake data about users. I was not able to find an OAS of it, so I made my own.
resources/openapi/jsonplaceholder.yaml
openapi: 3.0.3
info:
version: 1.0.0
title: JSON Placeholder API
description: See https://jsonplaceholder.typicode.com/
servers:
- url: "https://jsonplaceholder.typicode.com/"
paths:
/users:
get:
tags:
- User
operationId: getUsers
summary: Get list of all users
responses:
"200":
description: List of all users
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/User"
default:
description: Error
content:
application/json:
schema:
type: object
components:
schemas:
Address:
description: User address
properties:
city:
description: Address city
example: "Gwenborough"
type: string
geo:
$ref: "#/components/schemas/Geo"
street:
description: Address street
example: "Kulas Light"
type: string
suite:
description: Address suit
example: "Apt. 556"
type: string
zipcode:
description: Adress zipcode
example: "92998-3874"
type: string
type: object
Company:
description: User company
properties:
bs:
description: Company business
example: "harness real-time e-markets"
type: string
catchPhrase:
description: Company catch phrase
example: "Multi-layered client-server neural-net"
type: string
name:
description: Company name
example: "Romaguera-Crona"
type: string
type: object
Geo:
description: Address geolocalization
properties:
lat:
description: Geolocalization latitude
example: "-37.3159"
type: string
lng:
description: Geolocalization longitude
example: "81.1496"
type: string
type: object
User:
properties:
address:
$ref: "#/components/schemas/Address"
company:
$ref: "#/components/schemas/Company"
email:
description: User email
example: "Sincere@april.biz"
type: string
id:
description: User id
example: 1
type: integer
name:
description: User name
example: "Leanne Graham"
type: string
phone:
description: User phone
example: "1-770-736-8031 x56442"
type: string
username:
description: User username
example: "Bret"
type: string
website:
description: User website
example: "hildegard.org"
type: string
type: object
3. Generate the interfaces.
Add a new execution task to the openapi-generator-maven-plugin .
Here I leave some ready copy-paste for you.
<execution>
<id>java (client) generation - <!-- todo: replace with the name of the OAS file -->.yaml</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/openapi/<!-- todo: replace with the name of the OAS file -->.yaml</inputSpec>
<generatorName>java</generatorName>
<library>feign</library>
<output>${project.build.directory}/generated-sources/openapi/</output>
<apiPackage><!--todo: apiPackage--></apiPackage>
<modelPackage><!--todo: modelPackage--></modelPackage>
<configOptions>
<feignClient>true</feignClient>
<interfaceOnly>true</interfaceOnly>
<useEnumCaseInsensitive>true</useEnumCaseInsensitive>
<useJakartaEe>true</useJakartaEe>
</configOptions>
</configuration>
</execution>
- Put the name of the OAS file: is the file that represent the contract of the REST endpoint you want to consume
- Fill the value of <apiPackage>: should be a java-style url that ends in .api (ie: com.typicode.jsonplaceholder.api)
- Fill the value of <modelPackage>: should be a java-style url that ends in .model (ie: com.typicode.jsonplaceholder.model)
It should look something like this:
Do a maven clean and compile.
If you check the target\generated-sources\openapi\ folder, you’ll find everything that was generated by the two execution tasks.
Next lecture
Pollito’s Opinion on Spring Boot Development 5: Configuration of feignClient interfaces