diff --git a/feign-hypermedia-client/README.md b/feign-hypermedia-client/README.md
new file mode 100644
index 0000000000..e6ade4d161
--- /dev/null
+++ b/feign-hypermedia-client/README.md
@@ -0,0 +1,5 @@
+## Feign Hypermedia Client ##
+
+This is the implementation of a [spring-hypermedia-api][1] client using Feign.
+
+[1]: https://github.com/eugenp/spring-hypermedia-api
diff --git a/feign-hypermedia-client/pom.xml b/feign-hypermedia-client/pom.xml
new file mode 100644
index 0000000000..7e60e2ec7f
--- /dev/null
+++ b/feign-hypermedia-client/pom.xml
@@ -0,0 +1,91 @@
+
+
+ 4.0.0
+
+ com.baeldung.feign
+ feign-hypermedia-client
+ 1.0.0-SNAPSHOT
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+ ..
+
+
+
+ UTF-8
+
+
+
+
+ io.github.openfeign
+ feign-core
+ 9.3.1
+
+
+ io.github.openfeign
+ feign-okhttp
+ 9.3.1
+
+
+ io.github.openfeign
+ feign-gson
+ 9.3.1
+
+
+ io.github.openfeign
+ feign-slf4j
+ 9.3.1
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.21
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.6.2
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+ 2.6.2
+
+
+ org.projectlombok
+ lombok
+ 1.16.10
+ provided
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.5.1
+
+
+ 1.8
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ 1.4.0.RELEASE
+
+
+
+
+
diff --git a/feign-hypermedia-client/src/main/java/com/baeldung/feign/Controller.java b/feign-hypermedia-client/src/main/java/com/baeldung/feign/Controller.java
new file mode 100644
index 0000000000..f5405be87a
--- /dev/null
+++ b/feign-hypermedia-client/src/main/java/com/baeldung/feign/Controller.java
@@ -0,0 +1,26 @@
+package com.baeldung.feign;
+
+import com.baeldung.feign.clients.BookClient;
+import feign.Feign;
+import feign.Logger;
+import feign.gson.GsonDecoder;
+import feign.gson.GsonEncoder;
+import feign.okhttp.OkHttpClient;
+import feign.slf4j.Slf4jLogger;
+import lombok.Getter;
+
+@Getter
+public class Controller {
+ private BookClient bookClient = createClient(BookClient.class,
+ "http://localhost:8081/api/books");
+
+ private static T createClient(Class type, String uri) {
+ return Feign.builder()
+ .client(new OkHttpClient())
+ .encoder(new GsonEncoder())
+ .decoder(new GsonDecoder())
+ .logger(new Slf4jLogger(type))
+ .logLevel(Logger.Level.FULL)
+ .target(type, uri);
+ }
+}
diff --git a/feign-hypermedia-client/src/main/java/com/baeldung/feign/clients/BookClient.java b/feign-hypermedia-client/src/main/java/com/baeldung/feign/clients/BookClient.java
new file mode 100644
index 0000000000..df20ef8f93
--- /dev/null
+++ b/feign-hypermedia-client/src/main/java/com/baeldung/feign/clients/BookClient.java
@@ -0,0 +1,21 @@
+package com.baeldung.feign.clients;
+
+import com.baeldung.feign.models.Book;
+import com.baeldung.feign.models.BookResource;
+import feign.Headers;
+import feign.Param;
+import feign.RequestLine;
+
+import java.util.List;
+
+public interface BookClient {
+ @RequestLine("GET /{isbn}")
+ BookResource findByIsbn(@Param("isbn") String isbn);
+
+ @RequestLine("GET")
+ List findAll();
+
+ @RequestLine("POST")
+ @Headers("Content-Type: application/json")
+ void create(Book book);
+}
diff --git a/feign-hypermedia-client/src/main/java/com/baeldung/feign/models/Book.java b/feign-hypermedia-client/src/main/java/com/baeldung/feign/models/Book.java
new file mode 100644
index 0000000000..cda4412e27
--- /dev/null
+++ b/feign-hypermedia-client/src/main/java/com/baeldung/feign/models/Book.java
@@ -0,0 +1,18 @@
+package com.baeldung.feign.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+@Data
+@ToString
+@NoArgsConstructor
+@AllArgsConstructor
+public class Book {
+ private String isbn;
+ private String author;
+ private String title;
+ private String synopsis;
+ private String language;
+}
diff --git a/feign-hypermedia-client/src/main/java/com/baeldung/feign/models/BookResource.java b/feign-hypermedia-client/src/main/java/com/baeldung/feign/models/BookResource.java
new file mode 100644
index 0000000000..7902db9fe8
--- /dev/null
+++ b/feign-hypermedia-client/src/main/java/com/baeldung/feign/models/BookResource.java
@@ -0,0 +1,14 @@
+package com.baeldung.feign.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+@Data
+@ToString
+@NoArgsConstructor
+@AllArgsConstructor
+public class BookResource {
+ private Book book;
+}
diff --git a/feign-hypermedia-client/src/main/resources/log4j2.xml b/feign-hypermedia-client/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000..659c5fda0e
--- /dev/null
+++ b/feign-hypermedia-client/src/main/resources/log4j2.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/feign-hypermedia-client/src/test/java/com/baeldung/feign/clients/BookClientTest.java b/feign-hypermedia-client/src/test/java/com/baeldung/feign/clients/BookClientTest.java
new file mode 100644
index 0000000000..dcebe7426f
--- /dev/null
+++ b/feign-hypermedia-client/src/test/java/com/baeldung/feign/clients/BookClientTest.java
@@ -0,0 +1,54 @@
+package com.baeldung.feign.clients;
+
+import com.baeldung.feign.Controller;
+import com.baeldung.feign.models.Book;
+import com.baeldung.feign.models.BookResource;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+@Slf4j
+@RunWith(JUnit4.class)
+public class BookClientTest {
+ private Controller controller = new Controller();
+
+ @Test
+ public void givenBookClient_shouldRunSuccessfully() throws Exception {
+ BookClient bookClient = controller.getBookClient();
+ List books = bookClient.findAll().stream()
+ .map(BookResource::getBook)
+ .collect(Collectors.toList());
+ assertTrue(books.size() > 2);
+ log.info("{}", books);
+ }
+
+ @Test
+ public void givenBookClient_shouldFindOneBook() throws Exception {
+ BookClient bookClient = controller.getBookClient();
+ Book book = bookClient.findByIsbn("0151072558").getBook();
+ assertThat(book.getAuthor(), containsString("Orwell"));
+ log.info("{}", book);
+ }
+
+ @Test
+ public void givenBookClient_shouldPostBook() throws Exception {
+ BookClient bookClient = controller.getBookClient();
+ String isbn = UUID.randomUUID().toString();
+ Book book = new Book(isbn, "Me", "It's me!", null, null);
+ bookClient.create(book);
+
+ book = bookClient.findByIsbn(isbn).getBook();
+ assertThat(book.getAuthor(), is("Me"));
+ log.info("{}", book);
+ }
+}