{"id":15196886,"url":"https://github.com/polysantiago/spring-boot-rest-client","last_synced_at":"2025-10-28T04:31:38.983Z","repository":{"id":57734508,"uuid":"86737608","full_name":"polysantiago/spring-boot-rest-client","owner":"polysantiago","description":"A Rest Client for Spring Boot","archived":false,"fork":false,"pushed_at":"2019-08-20T09:28:17.000Z","size":316,"stargazers_count":19,"open_issues_count":2,"forks_count":10,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-01T11:24:51.478Z","etag":null,"topics":["annotations","bean","hateoas","java-8","microservices","rest-microservice","retries","spring-boot","spring-framework","spring-mvc","spring-rest"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/polysantiago.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-03-30T18:52:23.000Z","updated_at":"2024-01-06T20:16:45.000Z","dependencies_parsed_at":"2022-09-11T16:40:56.189Z","dependency_job_id":null,"html_url":"https://github.com/polysantiago/spring-boot-rest-client","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polysantiago%2Fspring-boot-rest-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polysantiago%2Fspring-boot-rest-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polysantiago%2Fspring-boot-rest-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polysantiago%2Fspring-boot-rest-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/polysantiago","download_url":"https://codeload.github.com/polysantiago/spring-boot-rest-client/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238597386,"owners_count":19498396,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["annotations","bean","hateoas","java-8","microservices","rest-microservice","retries","spring-boot","spring-framework","spring-mvc","spring-rest"],"created_at":"2024-09-28T00:05:47.602Z","updated_at":"2025-10-28T04:31:33.625Z","avatar_url":"https://github.com/polysantiago.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"Spring Boot Rest Client\n=======\n\n[![Build Status](https://travis-ci.org/polysantiago/spring-boot-rest-client.svg?branch=master)](https://travis-ci.org/polysantiago/spring-boot-rest-client)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.github.polysantiago/spring-boot-rest-client/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.github.polysantiago/spring-boot-rest-client)\n[![GitHub issues](https://img.shields.io/github/issues/polysantiago/spring-boot-rest-client.svg)](https://github.com/polysantiago/spring-boot-rest-client/issues)\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/polysantiago/spring-boot-rest-client/master/LICENSE)\n\nThis library was born as an effort to avoid boilerplate code and making use of Spring Boot's auto-configuration features.\n\nIt is based on [Spring Cloud Feign](http://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign) but it \nuses [RestTemplate](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html) \ninstead of Netflix's Feign and [Spring MVC annotations](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html).\n\nAs an additional feature, **spring-boot-rest-client** supports [Spring Retry](https://github.com/spring-projects/spring-retry) \nso that HTTP requests can be retried upon either specific HTTP statuses and/or defined Exceptions.\n\nUsage\n-----\n\n```java\n@EnableRestClients\n@SpringBootApplication\npublic class FooApplication {\n    \n    public static void main(String... args) {\n        SpringApplication.run(FooApplication.class, args);\n    }\n    \n    @RestClient(\"foo\")\n    interface FooClient {\n    \n        @RequestMapping\n        Foo getFoo();\n    \n    }\n    \n}\n```\n\n```yaml\nspring:\n  rest:\n    client:\n      services:\n        foo: http://foo.bar.se\n```\n    \nYou can later use `@Autowired` (or constructor injection) and just call `fooClient.getFoo()` which will \nmake an `HTTP GET` call to `http://foo.bar.se`\n\n```java\n@Component\npublic class RestClientConsumer {\n    \n    private final FooClient fooClient;\n    \n    RestClientConsumer(FooClient fooClient) {\n        this.fooClient = fooClient;\n    }\n    \n    public Foo getFoo() {\n        return fooClient.getFoo();\n    }\n    \n}\n```\n\nStructure\n-----\n`@RequestMapping` values have the following correspondence to the resulting HTTP call:\n    \n* `value()` - Path appended to the host\n* `method()` - The HTTP method (GET is the default)\n* `produces()` - Value of the [Accept](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1) header\n* `consumes()` - Value of the [Content-Type](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17) header\n* `headers()` - `String[]` of key-value pairs of headers separated by ':'\n\nAll HTTP REST methods are supported (GET, POST, PUT, PATCH and DELETE) as well as the following annotations on parameters:\n\n* [RequestParam](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html)\n* [PathVariable](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/PathVariable.html)\n* [RequestHeader](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestHeader.html)\n* [RequestBody](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestBody.html)\n \nA method parameter with no annotation is expected to be the request body (payload) of the request \nif `@RequestBody` is not specified.\n\nIn addition to `@RequestMapping`, composed variants introduced in Spring MVC 4.3 can also be used.\nCheck [this](https://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-composed)\nfor more details.\n\nAsync\n-----\nSpring Boot Rest Template can be also be configured to be used for asynchronous REST calls for which it will instead use\nan `AsyncRestTemplate` bean. It supports both Oracle's [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html) \nas well as Spring's [ListenableFuture](http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/util/concurrent/ListenableFuture.html).\n\n```java\n@RestClient(\"foo\")\ninterface FooClient {\n    \n    @RequestMapping(\"/{id}\")\n    ListenableFuture\u003cString\u003e foo(@PathVariable(\"id\") String id, @RequestParam(\"query\") String query);\n    \n    @RequestMapping(value = \"/{id}\", produces = MediaType.APPLICATION_JSON_VALUE)\n    CompletableFuture\u003cFoo\u003e getFoo(@PathVariable(\"id\") String id);\n    \n}\n```\n\nPlease note that retry functionality is currently not supported for asynchronous requests.\n\nGenerics\n-----\nGeneric declarations are supported as long as the \"implementing\" interface contains a concrete class.\n\nWorking example:\n\n```java\ninterface FooBaseClient\u003cT\u003e {\n    \n    @GetMapping(value = \"/{id}\")\n    T getParameterized(@PathVariable(\"id\") String id);\n    \n}\n```\n```java\n@RestClient(\"foo\")\ninterface FooClient extends FooBaseClient\u003cFoo\u003e {\n    \n}\n```\n\nHTTP Entities\n-----\nIf for some reason you do not wish to have the body extracted from your response, you can wrap your response type in\neither a [ResponseEntity](http://docs.spring.io/autorepo/docs/spring/current/javadoc-api/org/springframework/http/ResponseEntity.html) \nas well as an [HttpEntity](http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpEntity.html).\n\n```java\n@RestClient(\"foo\")\ninterface FooClient {\n    \n    @GetMapping\n    ResponseEntity\u003cString\u003e getEntity();\n    \n    @GetMapping\n    HttpEntity\u003cString\u003e getHttpEntity();\n    \n}\n```\n\nJDK 8 Support\n-----\nIf you wrap your response type in Oracle's JDK 8 [Optional](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html),\nSpring Boot Rest Client will return an `Optional.empty()` upon a `HTTP 404 NOT FOUND` response code.\n\n```java\n@RestClient(\"foo\")\ninterface FooClient {\n    \n    @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)\n    Optional\u003cFoo\u003e getOptional();\n    \n}\n```\n\nPlease note that **default** methods in interfaces declaring `@RestClient` are currently not supported.\n\nHATEOAS Support\n-----\n\nSpecially useful for [HATEOAS](https://en.wikipedia.org/wiki/HATEOAS), you can use the `@PostForLocation` annotation to\nindicate that a POST request should return the `Location` HTTP header as an `URI`.\n\n```java\n@RestClient(\"foo\")\ninterface FooClient {\n    \n    @PostForLocation(\"/postForLocation\")\n    URI postForLocation(String body);\n    \n}\n```\n\nAdditionally, by including [Spring HATEOAS](https://github.com/spring-projects/spring-hateoas) as a dependency, you can \nuse Spring HATEOAS resource support:\n\n```java\npublic class FooResource extends ResourceSupport {\n    \n}\n```\n```java\n@RestClient(\"foo\")\ninterface FooClient {\n  \n    @GetMapping(value = \"/foo/{id}\", produces = MediaTypes.HAL_JSON_VALUE)\n    FooResource getFoo(@PathVariable(\"id\") String id);\n    \n    @GetMapping(value = \"/foo/{id}\", produces = MediaTypes.HAL_JSON_VALUE)\n    Resource\u003cFoo\u003e getFooWrapped(@PathVariable(\"id\") String id);\n    \n    @GetMapping(value = \"/foos\", produces = MediaTypes.HAL_JSON_VALUE)\n    Resources\u003cFooResource\u003e getFoos();\n    \n    @GetMapping(value = \"/foos\", produces = MediaTypes.HAL_JSON_VALUE)\n    PagedResources\u003cFooResource\u003e getPagedFoos();\n    \n}\n```\n \nRetry\n-----\n\nThe rest client library can be used with Spring Retry. Just by adding the `org.springframework.retry:spring-retry` \nlibrary as a dependency and `@EnableRetry` in your configuration, the retry functionality will be enabled.\nBy default, calls are retried on `HTTP 503 SERVICE UNAVAILABLE` and `IOException` but you can configure your own:\n\n```java\n@RestClient(\n    value = \"foo\", \n    retryOn = {HttpStatus.SERVICE_UNAVAILABLE, HttpStatus.BAD_GATEWAY}, \n    retryOnException = SocketTimeoutException.class)\ninterface FooClient {\n    \n    @RestClient(\"/foos\")\n    List\u003cFoo\u003e getFooList();\n    \n}\n```\n    \nFurthermore, global retry settings can be configured by adding values to `application.yml`. Below, the default values\nare shown:\n\n```yaml\nspring:\n  rest:\n    client:\n      services:\n        foo: http://foo.bar.se\n      retry:\n        max-attempts: 3\n        back-off:\n          delay: 1000\n          max-delay: 0\n          multiplier: 0.0\n          random: false\n```\n\nRefer to [Spring Retry](https://github.com/spring-projects/spring-retry) for more information about what the values refer to.\n    \nMiscellaneous\n-------------\n\n* The library will create a `RestTemplate` and a `AsyncRestTemplate` Spring beans if not already present using a\n[RestTemplateBuilder](http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/web/client/RestTemplateBuilder.html)\n* The library is non-intrusive. That means that if you want the spring-retry functionality you'll need to include it and \nall of its dependencies\n* `@RestClient` also accepts an optional `url()` parameter which can be either a hardcoded value \nor a [SpEL expression](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/expressions.html) \n\nTODO\n----\n\n* Add option to disable retry on either clients or specific methods\n* Support `@Recover` method as specified in Spring Retry when retries are exhausted","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolysantiago%2Fspring-boot-rest-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpolysantiago%2Fspring-boot-rest-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolysantiago%2Fspring-boot-rest-client/lists"}