10.6 Calling REST Services with HttpClient
Calling Grails REST services - as well as third-party services - is very straightforward using the Micronaut HTTP Client. This HTTP client has both a low-level API and a higher level AOP-driven API, making it useful for both simple requests as well as building declarative, type-safe API layers.
To use the Micronaut HTTP client you must have the micronaut-http-client
dependency on your classpath. Add the following dependency to your build.gradle
file.
build.gradle
compile 'io.micronaut:micronaut-http-client'
Low-level API
The HttpClient interface forms the basis for the low-level API. This interfaces declares methods to help ease executing HTTP requests and receive responses.
The majority of the methods in the HttpClient
interface returns Reactive Streams Publisher instances, and a sub-interface called RxHttpClient is included that provides a variation of the HttpClient interface that returns RxJava Flowable types. When using HttpClient
in a blocking flow, you may wish to call toBlocking()
to return an instance of BlockingHttpClient.
There are a few ways by which you can obtain a reference to a HttpClient. The most simple way is using the create method
Creating an HTTP client
List<Album> searchWithApi(String searchTerm) {
String baseUrl = "https://itunes.apple.com/"
HttpClient client = HttpClient.create(baseUrl.toURL()).toBlocking() (1)
HttpRequest request = HttpRequest.GET("/search?limit=25&media=music&entity=album&term=${searchTerm}")
HttpResponse<String> resp = client.exchange(request, String)
client.close() (2)
String json = resp.body()
ObjectMapper objectMapper = new ObjectMapper() (3)
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
SearchResult searchResult = objectMapper.readValue(json, SearchResult)
searchResult.results
}
1 | Create a new instance of HttpClient with the create method, and convert to an instance of BlockingHttpClient with toBlocking() , |
2 | The client should be closed using the close method to prevent thread leaking. |
3 | Jackson’s ObjectMapper API can be used to map the raw JSON to POGOs, in this case SearchResult |
Consult the Http Client section of the Micronaut user guide for more information on using the HttpClient
low-level API.
Declarative API
A declarative HTTP client can be written by adding the @Client
annotation to any interface or abstract class. Using Micronaut’s AOP support (see the Micronaut user guide section on Introduction Advice), the abstract or interface methods will be implemented for you at compilation time as HTTP calls. Declarative clients can return data-bound POGOs (or POJOs) without requiring special handling from the calling code.
package example.grails
import io.micronaut.http.annotation.Get
import io.micronaut.http.client.annotation.Client
@Client("https://itunes.apple.com/")
interface ItunesClient {
@Get("/search?limit=25&media=music&entity=album&term={term}")
SearchResult search(String term)
}
Note that HTTP client methods are annotated with the appropriate HTTP method, such as @Get
or @Post
.
To use a client like the one in the above example, simply inject an instance of the client into any bean using the @Autowired
annotation.
@Autowired
ItunesClient itunesClient
List<Album> searchAlbums(String searchTerm) {
SearchResult searchResult = itunesClient.search(searchTerm)
searchResult.results
}
For more details on writing and using declarative clients, consult the Http Client section of the Micronaut user guide.