rest-request is a tool that makes it easy to create many parameters that need to be generated when using Spring Web's RestTemplate
.
rest-request is inspired by Spring Webflux's WebClient
, which similarly allows method-chaining methods to create HTTP Headers, Query Parameters, Form Data, Request Body, and more.
RestRequest<ResponseType> request = RestRequest.resp(ResponseType.class)
.uri("http://www.api.com/resources")
.post()
.addHeader("X-Test-Header-Name", "XTestHeaderValue")
.addParam("queryParamKey", "queryParamValue")
.body(requestBodyObject)
.build();
ResponsType response = restTemplate.exchange(request.getUri(),
request.getMethod(),
request.getHttpEntity(),
request.getResponseType());
As above, you can easily and readably generate all the information you need for RestTemplate
.
rest-request provides RestRequest
object that creates request information, and generated in the following order:
There are four types of responses:
-
- Preference :
Map<String, Object>
- Preference :
-
- T type :
Class<T>
- T type :
-
- Generic T type :
ParameterizedTypeReference<T>
- Generic T type :
-
- Void type :
Class<Void>
- Void type :
// 1. Preference : Map<String, Object>
RestRequest.mapResp()
// 2. T type : Class<T>
RestRequest.resp(ResponseType.class)
// 3. Generic T type : ParameterizedTypeReference<T>
RestRequest.resp(new ParameterizedTypeReference<List<ResponseType>>(){})
// 4. Void type : Class<Void>
RestRequest.nonResp()
The URI to request supports paramters of the java.net.URI
or String
type.
// java.net.URI type
URI uri = URI.create("http://www.api.com/resources");
RestRequest.resp(ResponseType.class)
.uri(uri)
// String type
RestRequest.resp(ResponseType.class)
.uri("http://www.api.com/resources")
HTTP Method can be specified by a method name with an intuitive name. The methods that supports it are GET / POST / PUT / PATCH / DELETE. Here, the POST / PUT / PATCH method allows you to set the Request Body in the near time.
RestRequest.resp(ResponseType.class)
.uri(uri)
.get() / .post() / .put() / .patch() / .delete()
Afterwards, you can set HTTP Headers, Query Parameters, Form Datas, and Request Body.
- HTTP Header
HTTP Header can be added as anaddHeader()
,accept()
,contentType()
,authorization()
,basicAuth()
andbearerToken()
methods.RestRequest.resp(ResponseType.class) .uri(uri) .get() .addHeader("headerName", "headerValue") .accept(MediaType.APPLICATION_JSON) // Support type : MediaType, String .contentType("application/json") // Support type : MediaType, String .authorization("authValue") .basicAuth("username", "password") .bearerToken("tokenValue")
- Form Parameter
You can add Form Parameters with theaddParam()
,setParams()
methods.
If you previously specifiedget()
/delete()
, Query Parameter is generated, and ifpost()
/put()
/patch()
is specified, Form Data is generated.
If both Request Body and Form Parameter are set, they are generated as Query Parameters, even ifpost()
/put()
/patch()
is specified.// Generate a Query Parameter RestRequest.resp(ResponseType.class) .uri(uri) .get() .addParam("paramKey", "paramValue") // Add Query Parameter : key-value .setParams(multiValueMap) // Add Query Parameter : MultiValueMap<String, Object> .setParams(map) // Add Query Parameter : Map<String, Object> .setParams(object) // Add Query Parameter : Object // Generate Form Datas RestRequest.resp(ResponseType.class) .uri(uri) .post() .addParam("paramKey", "paramValue")
- Request Body
You can set it as abody()
method. (You can call thebody()
method only when specifyingpost()
/put()
/patch()
methods.)RestRequest.resp(ResponseType.class) .put() .addParam("queryParamKey", "queryParamValue") // Generate Query Parameter .body(requestBodyObject)
- Attach File
You can set it as aaddFile()
method. The supported parameter types areFile
,Path
, andMultipartFile
. If the Content Type header is not set, it is automatically set to the valuemultipart/form-data
.If Request Body is set, it is set toRestRequest.resp(ResponseType.class) .post() .addFile("file1", new File("test.txt")) .addFile("file2", Paths.get("test.txt")) .addFile("file3", multipartFile)
multipart/mixed
. However, since Request Body is set as a key calledbody
in the form data, it is recommended to set it directly usingaddParam()
if possible. (You can call theaddFile()
method only when specifyingpost()
/put()
/patch()
methods.)RestRequest.resp(ResponseType.class) .uri(uri) .post() .contentType(MediaType.MULTIPART_MIXED) .addParam("json", new ObjectMapper().writeValueAsString(body)) .addFile("attach", Paths.get("test.txt")) .build();
Finally, call build()
method to generate RestRequest
.
RestRequest
can load the following properties:
URI
HttpMethod
HttpEntity
Class<T>
ParameterizedTypeReference<T>
// Class<T> when specifying
RestRequest<ResponseType> request = RestRequest.resp(ResponseType.class)
.uri(uri)
.get()
.build();
ResponseType response = restTemplate.exchange(request.getUri(),
request.getMethod(),
request.getHttpEntity(),
request.getResponseType());
// ParameterizedTypeReference<T> when specifying
RestRequest<List<ResponseType>> request = RestRequest.resp(new ParameterizedTypeReference<List<ResponseType>>(){})
.uri(uri)
.get()
.build();
List<ResponseType> response = restTemplate.exchange(request.getUri(),
request.getMethod(),
request.getHttpEntity(),
request.getTypeReference());
rest-request provides RestClientAdapter
, a class that works with RestRequest
and RestTemplate
.
RestClientAdapter
can be generated as a Bean in two ways:
@Configuration
public class WebConfig {
@Bean
@ConditionalOnMissingBean(RestTemplate.class)
public RestClientAdapter restClientAdapter() {
return new DefaultRestClientAdpater();
}
@Bean
@ConditionalOnBean(RestTemplate.class)
public RestClientAdapter restClientAdapter(final RestTemplate restTemplate) {
return new DefaultRestClientAdapter(restTemplate);
}
}
DefaultRestClientAdapter
default constructor is internally generated using new RestTemplate()
.
Or, if you have RestTemplate
generated by Bean, you're injected with that RestTemplate
.
RestClientAdapter
can be used as follows:
@Service
public class WebService {
@Autowired
private RestClientAdpater restClient;
public ResponseEntity<Resource> getSome(ResourceDto dto) {
return restClient.send(RestRequest.resp(Resource.class)
.uri("http://www.api.com/resources")
.get()
.setParams(dto)
.build());
}
public Optional<Resource> postSome(Resource resource) {
return restClient.sendForBody(RestRequest.resp(Resource.class)
.uri("http://www.api.com/resources")
.post()
.body(resource)
.build());
}
public CompletableFuture<ResponseEntity<Resource>> getSomeAsync(ResourceDto dto) {
return restClient.sendAsync(RestRequest.resp(Resource.class)
.uri("http://www.api.com/resources")
.get()
.setParams(dto)
.build());
}
public CompletableFuture<ResponseEntity<Resource>> getSomeAsync(ResourceDto dto, Executor executor) {
return restClient.sendAsync(RestRequest.resp(Resource.class)
.uri("http://www.api.com/resources")
.get()
.setParams(dto)
.build(),
executor);
}
}
- Java 8 or higher
- Spring Web 5.3.25 or higher
<dependency>
<groupId>io.github.libedi</groupId>
<artifactId>rest-request</artifactId>
<version>2.1.2</version>
</dependency>
implementation 'io.github.libedi:rest-request:2.1.2'