diff --git a/README.md b/README.md
index e28eef6..1fb0294 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ public interface PostService {
// Use CleverClient to call the API
var cleverClient = CleverClient.builder()
- .urlBase("https://jsonplaceholder.typicode.com/")
+ .baseUrl("https://jsonplaceholder.typicode.com/")
.build();
var postService = cleverClient.create(PostService.class);
@@ -97,7 +97,7 @@ We have the following attributes to create a CleverClient object:
| Attribute | Description | Required |
| ----------- |----------------------------------------|-----------|
-| urlBase | Api's url | mandatory |
+| baseUrl | Api's url | mandatory |
| headers | Pairs of headers name/value | optional |
| httpClient | Java HttpClient object | optional |
| endOfStream | Text used to mark the final of streams | optional |
@@ -107,7 +107,7 @@ The attribute ```endOfStream``` is required when you have endpoints sending back
Example:
```java
-final var URL_BASE = "https://api.example.com";
+final var BASE_URL = "https://api.example.com";
final var HEADER_NAME = "Authorization";
final var HEADER_VALUE = "Bearer qwertyasdfghzxcvb";
final var END_OF_STREAM = "[DONE]";
@@ -121,7 +121,7 @@ var httpClient = HttpClient.newBuilder()
.build();
var cleverClient = CleverClient.builder()
- .urlBase(URL_BASE)
+ .baseUrl(BASE_URL)
.headers(Arrays.asList(HEADER_NAME, HEADER_VALUE))
.httpClient(httpClient)
.endOfStream(END_OF_STREAM)
diff --git a/pom.xml b/pom.xml
index c1ed707..0e12b28 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
io.github.sashirestela
cleverclient
- 0.12.0
+ 0.13.0
jar
cleverclient
diff --git a/src/example/java/io/github/sashirestela/cleverclient/example/BasicExample.java b/src/example/java/io/github/sashirestela/cleverclient/example/BasicExample.java
index 758372c..6407feb 100644
--- a/src/example/java/io/github/sashirestela/cleverclient/example/BasicExample.java
+++ b/src/example/java/io/github/sashirestela/cleverclient/example/BasicExample.java
@@ -7,10 +7,10 @@
public class BasicExample {
public static void main(String[] args) {
- final var URL_BASE = "https://jsonplaceholder.typicode.com";
+ final var BASE_URL = "https://jsonplaceholder.typicode.com";
var cleverClient = CleverClient.builder()
- .urlBase(URL_BASE)
+ .baseUrl(BASE_URL)
.build();
var postService = cleverClient.create(PostService.class);
diff --git a/src/example/java/io/github/sashirestela/cleverclient/example/FileDownloadExample.java b/src/example/java/io/github/sashirestela/cleverclient/example/FileDownloadExample.java
index a07bb71..42ded38 100644
--- a/src/example/java/io/github/sashirestela/cleverclient/example/FileDownloadExample.java
+++ b/src/example/java/io/github/sashirestela/cleverclient/example/FileDownloadExample.java
@@ -17,10 +17,10 @@ static interface ImageService {
}
public static void main(String[] args) throws IOException {
- final var URL_BASE = "https://via.placeholder.com";
+ final var BASE_URL = "https://via.placeholder.com";
var cleverClient = CleverClient.builder()
- .urlBase(URL_BASE)
+ .baseUrl(BASE_URL)
.build();
var imageService = cleverClient.create(ImageService.class);
diff --git a/src/example/java/io/github/sashirestela/cleverclient/example/HeaderExample.java b/src/example/java/io/github/sashirestela/cleverclient/example/HeaderExample.java
index 9d4a39e..3960a01 100644
--- a/src/example/java/io/github/sashirestela/cleverclient/example/HeaderExample.java
+++ b/src/example/java/io/github/sashirestela/cleverclient/example/HeaderExample.java
@@ -27,10 +27,10 @@ static interface MethodHeaderService {
}
public static void main(String[] args) {
- final var URL_BASE = "https://httpbin.org";
+ final var BASE_URL = "https://httpbin.org";
var cleverClient = CleverClient.builder()
- .urlBase(URL_BASE)
+ .baseUrl(BASE_URL)
.build();
var classHeaderService = cleverClient.create(ClassHeaderService.class);
diff --git a/src/example/java/io/github/sashirestela/cleverclient/example/MultiServiceExample.java b/src/example/java/io/github/sashirestela/cleverclient/example/MultiServiceExample.java
index 91de837..e16bbc4 100644
--- a/src/example/java/io/github/sashirestela/cleverclient/example/MultiServiceExample.java
+++ b/src/example/java/io/github/sashirestela/cleverclient/example/MultiServiceExample.java
@@ -7,10 +7,10 @@
public class MultiServiceExample {
public static void main(String[] args) {
- final var URL_BASE = "https://jsonplaceholder.typicode.com";
+ final var BASE_URL = "https://jsonplaceholder.typicode.com";
var cleverClient = CleverClient.builder()
- .urlBase(URL_BASE)
+ .baseUrl(BASE_URL)
.build();
var postService = cleverClient.create(PostService.class);
var albumService = cleverClient.create(AlbumService.class);
diff --git a/src/example/java/io/github/sashirestela/cleverclient/example/StreamExample.java b/src/example/java/io/github/sashirestela/cleverclient/example/StreamExample.java
index 139ea83..594a62c 100644
--- a/src/example/java/io/github/sashirestela/cleverclient/example/StreamExample.java
+++ b/src/example/java/io/github/sashirestela/cleverclient/example/StreamExample.java
@@ -17,13 +17,13 @@
public class StreamExample {
public static void main(String[] args) {
- final var URL_BASE = "https://api.openai.com";
+ final var BASE_URL = "https://api.openai.com";
final var AUTHORIZATION_HEADER = "Authorization";
final var BEARER_AUTHORIZATION = "Bearer " + System.getenv("OPENAI_API_KEY");
final var END_OF_STREAM = "[DONE]";
var cleverClient = CleverClient.builder()
- .urlBase(URL_BASE)
+ .baseUrl(BASE_URL)
.headers(Arrays.asList(AUTHORIZATION_HEADER, BEARER_AUTHORIZATION))
.endOfStream(END_OF_STREAM)
.build();
diff --git a/src/main/java/io/github/sashirestela/cleverclient/CleverClient.java b/src/main/java/io/github/sashirestela/cleverclient/CleverClient.java
index e1b9ad3..5f31164 100644
--- a/src/main/java/io/github/sashirestela/cleverclient/CleverClient.java
+++ b/src/main/java/io/github/sashirestela/cleverclient/CleverClient.java
@@ -1,5 +1,7 @@
package io.github.sashirestela.cleverclient;
+import static io.github.sashirestela.cleverclient.util.CommonUtil.isNullOrEmpty;
+
import java.net.http.HttpClient;
import java.util.List;
import java.util.Optional;
@@ -12,7 +14,6 @@
import io.github.sashirestela.cleverclient.support.CleverClientSSE;
import lombok.Builder;
import lombok.Getter;
-import lombok.NonNull;
import lombok.Singular;
/**
@@ -22,17 +23,25 @@
*/
@Getter
public class CleverClient {
- private static Logger logger = LoggerFactory.getLogger(CleverClient.class);
+ private static final Logger logger = LoggerFactory.getLogger(CleverClient.class);
- private String urlBase;
- private List headers;
- private HttpClient httpClient;
- private HttpProcessor httpProcessor;
+ private final String baseUrl;
+ @Deprecated
+ private final String urlBase = null;
+ private final List headers;
+ private final HttpClient httpClient;
+ private final HttpProcessor httpProcessor;
/**
* Constructor to create an instance of CleverClient.
*
- * @param urlBase Root of the url of the API service to call. Mandatory.
+ * @param baseUrl Root of the url of the API service to call.
+ * at least one of baseUrl and the deprecated urlBase is mandatory.
+ * in case both are specified and different baseUrl takes precedence
+ *
+ * @param urlBase [[ Deprecated ]] Root of the url of the API service to call.
+ * it is here for backward compatibility only. It will be removed in
+ * a future version. use `baseUrl()` instead.
* @param headers Http headers for all the API service. Header's name and
* value must be individual entries in the list. Optional.
* @param httpClient Custom Java's HttpClient component. One is created by
@@ -41,16 +50,19 @@ public class CleverClient {
* server sent events (SSE). Optional.
*/
@Builder
- public CleverClient(@NonNull String urlBase, @Singular List headers, HttpClient httpClient,
+ public CleverClient(String baseUrl, String urlBase, @Singular List headers, HttpClient httpClient,
String endOfStream) {
- this.urlBase = urlBase;
+ if (isNullOrEmpty(baseUrl) && isNullOrEmpty(urlBase)) {
+ throw new CleverClientException("At least one of baseUrl and urlBase is mandatory.", null, null);
+ }
+ this.baseUrl = isNullOrEmpty(baseUrl) ? urlBase : baseUrl;
this.headers = Optional.ofNullable(headers).orElse(List.of());
if (this.headers.size() % 2 > 0) {
throw new CleverClientException("Headers must be entered as pair of values in the list.", null, null);
}
this.httpClient = Optional.ofNullable(httpClient).orElse(HttpClient.newHttpClient());
CleverClientSSE.setEndOfStream(endOfStream);
- this.httpProcessor = new HttpProcessor(this.urlBase, this.headers, this.httpClient);
+ this.httpProcessor = new HttpProcessor(this.baseUrl, this.headers, this.httpClient);
logger.debug("CleverClient has been created.");
}
diff --git a/src/main/java/io/github/sashirestela/cleverclient/http/HttpProcessor.java b/src/main/java/io/github/sashirestela/cleverclient/http/HttpProcessor.java
index d5baa46..01ba735 100644
--- a/src/main/java/io/github/sashirestela/cleverclient/http/HttpProcessor.java
+++ b/src/main/java/io/github/sashirestela/cleverclient/http/HttpProcessor.java
@@ -22,19 +22,19 @@
public class HttpProcessor implements InvocationHandler {
private static final Logger logger = LoggerFactory.getLogger(HttpProcessor.class);
- private HttpClient httpClient;
- private String urlBase;
- private List headers;
+ private final HttpClient httpClient;
+ private final String baseUrl;
+ private final List headers;
/**
* Constructor to create an instance of HttpProcessor.
*
* @param httpClient Java's HttpClient component that solves the http calling.
- * @param urlBase Root of the url of the API service to call.
+ * @param baseUrl Root of the url of the API service to call.
* @param headers Http headers for all the API service.
*/
- public HttpProcessor(String urlBase, List headers, HttpClient httpClient) {
- this.urlBase = urlBase;
+ public HttpProcessor(String baseUrl, List headers, HttpClient httpClient) {
+ this.baseUrl = baseUrl;
this.headers = headers;
this.httpClient = httpClient;
}
@@ -93,7 +93,7 @@ public Object invoke(Object proxy, Method method, Object[] arguments) throws Thr
/**
* Reads the interface method metadata from memory and uses them to prepare an
* HttpConnector object that will resend the request to the Java's HttpClient
- * and will receive the response. This method is called from the invoke mehod.
+ * and will receive the response. This method is called from the invoke method.
*
* @param method The Method instance corresponding to the interface method
* invoked on the proxy instance.
@@ -106,7 +106,7 @@ private Object resolve(Method method, Object[] arguments) {
var interfaceMetadata = InterfaceMetadataStore.one().get(method.getDeclaringClass());
var methodMetadata = interfaceMetadata.getMethodBySignature().get(method.toString());
var urlMethod = interfaceMetadata.getFullUrlByMethod(methodMetadata);
- var url = urlBase + URLBuilder.one().build(urlMethod, methodMetadata, arguments);
+ var url = baseUrl + URLBuilder.one().build(urlMethod, methodMetadata, arguments);
var httpMethod = methodMetadata.getHttpAnnotationName();
var returnType = methodMetadata.getReturnType();
var isMultipart = methodMetadata.isMultipart();
diff --git a/src/main/java/io/github/sashirestela/cleverclient/metadata/InterfaceMetadataStore.java b/src/main/java/io/github/sashirestela/cleverclient/metadata/InterfaceMetadataStore.java
index f6c221f..36d00a0 100644
--- a/src/main/java/io/github/sashirestela/cleverclient/metadata/InterfaceMetadataStore.java
+++ b/src/main/java/io/github/sashirestela/cleverclient/metadata/InterfaceMetadataStore.java
@@ -68,7 +68,7 @@ public InterfaceMetadata get(Class> interfaceClass) {
if (interfacesByFullName.containsKey(interfaceClass.getName())) {
return interfacesByFullName.get(interfaceClass.getName());
} else {
- throw new CleverClientException("The interaface {0} has not been saved yet.", interfaceClass.getSimpleName(),
+ throw new CleverClientException("The interface {0} has not been saved yet.", interfaceClass.getSimpleName(),
null);
}
}
@@ -125,7 +125,7 @@ private void validate(InterfaceMetadata interfaceMetadata) {
interfaceMetadata.getMethodBySignature().forEach((methodSignature, methodMetadata) -> {
if (!methodMetadata.isDefault()) {
if (!methodMetadata.hasHttpAnnotation()) {
- throw new CleverClientException("Missing HTTP anotation for the method {0}.",
+ throw new CleverClientException("Missing HTTP annotation for the method {0}.",
methodMetadata.getName(), null);
}
}
diff --git a/src/test/java/io/github/sashirestela/cleverclient/CleverClientTest.java b/src/test/java/io/github/sashirestela/cleverclient/CleverClientTest.java
index ad53c7c..f3b6566 100644
--- a/src/test/java/io/github/sashirestela/cleverclient/CleverClientTest.java
+++ b/src/test/java/io/github/sashirestela/cleverclient/CleverClientTest.java
@@ -3,7 +3,6 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
import java.net.http.HttpClient;
import java.util.List;
@@ -16,53 +15,69 @@
class CleverClientTest {
- @Test
- void shouldSetPropertiesToDefaultValuesWhenBuilderIsCalledWithoutThoseProperties() {
- var cleverClient = CleverClient.builder()
- .urlBase("https://test")
- .build();
- assertEquals(List.of(), cleverClient.getHeaders());
- assertEquals(HttpClient.Version.HTTP_2, cleverClient.getHttpClient().version());
- assertNotNull(cleverClient.getUrlBase());
- assertNotNull(cleverClient.getHttpProcessor());
- }
- @Test
- void shouldImplementInterfaceWhenCallingCreate() {
- var cleverClient = CleverClient.builder()
- .urlBase("https://test")
- .header("headerName")
- .header("headerValue")
- .httpClient(HttpClient.newHttpClient())
- .endOfStream("[DONE]")
- .build();
- var test = cleverClient.create(TestCleverClient.class);
- assertNotNull(test);
- }
+ @Test
+ void shouldSetPropertiesToDefaultValuesWhenBuilderIsCalledWithoutThoseProperties() {
+ var cleverClient = CleverClient.builder()
+ .baseUrl("https://test")
+ .build();
+ assertEquals(List.of(), cleverClient.getHeaders());
+ assertEquals(HttpClient.Version.HTTP_2, cleverClient.getHttpClient().version());
+ assertNotNull(cleverClient.getBaseUrl());
+ assertNotNull(cleverClient.getHttpProcessor());
+ }
- @Test
- void shouldThrownExceptionWhenTryingToPassAnEmptyUrlBase() {
- var cleverClientBuilder = CleverClient.builder()
- .header("headerName")
- .header("headerValue")
- .httpClient(HttpClient.newHttpClient())
- .endOfStream("[DONE]");
- assertThrows(NullPointerException.class,
- () -> cleverClientBuilder.build());
- }
+ @Test
+ void shouldBuildSuccessfullyUsingDeprecatedUrlBase() {
+ var baseUrl = "https://test";
+ var cleverClient = CleverClient.builder()
+ .urlBase(baseUrl)
+ .build();
+ assertEquals(List.of(), cleverClient.getHeaders());
+ assertEquals(HttpClient.Version.HTTP_2, cleverClient.getHttpClient().version());
+ // verify that baseUrl is set when building with the deprecated urlBase() method
+ assertEquals(cleverClient.getBaseUrl(), baseUrl);
+ assertNotNull(cleverClient.getHttpProcessor());
+ }
- @Test
- void shouldThrownExceptionWhenTryingToPassAnOddNumbersOfHeaders() {
- var cleverClientBuilder = CleverClient.builder()
- .urlBase("http://test")
- .header("oneHeader");
- Exception exception = assertThrows(CleverClientException.class,
- () -> cleverClientBuilder.build());
- assertTrue(exception.getMessage().equals("Headers must be entered as pair of values in the list."));
- }
+ @Test
+ void shouldImplementInterfaceWhenCallingCreate() {
+ var cleverClient = CleverClient.builder()
+ .baseUrl("https://test")
+ .header("headerName")
+ .header("headerValue")
+ .httpClient(HttpClient.newHttpClient())
+ .endOfStream("[DONE]")
+ .build();
+ var test = cleverClient.create(TestCleverClient.class);
+ assertNotNull(test);
+ }
- interface TestCleverClient {
- @GET("/api/")
- CompletableFuture getText();
- }
+ @Test
+ void shouldThrownExceptionWhenTryingToPassAnEmptyBaseUrlAndUrlBase() {
+ var cleverClientBuilder = CleverClient.builder()
+ .header("headerName")
+ .header("headerValue")
+ .httpClient(HttpClient.newHttpClient())
+ .endOfStream("[DONE]");
+ assertThrows(CleverClientException.class,
+ cleverClientBuilder::build);
+ }
+
+ @Test
+ void shouldThrownExceptionWhenTryingToPassAnOddNumbersOfHeaders() {
+ var cleverClientBuilder = CleverClient.builder()
+ .baseUrl("http://test")
+ .header("oneHeader");
+ Exception exception = assertThrows(CleverClientException.class,
+ cleverClientBuilder::build);
+ assertEquals("Headers must be entered as pair of values in the list.",
+ exception.getMessage());
+ }
+
+ interface TestCleverClient {
+
+ @GET("/api/")
+ CompletableFuture getText();
+ }
}
diff --git a/src/test/java/io/github/sashirestela/cleverclient/metadata/InterfaceMetadataStoreTest.java b/src/test/java/io/github/sashirestela/cleverclient/metadata/InterfaceMetadataStoreTest.java
index 5a03b79..e1c834b 100644
--- a/src/test/java/io/github/sashirestela/cleverclient/metadata/InterfaceMetadataStoreTest.java
+++ b/src/test/java/io/github/sashirestela/cleverclient/metadata/InterfaceMetadataStoreTest.java
@@ -135,23 +135,22 @@ void shouldSaveInterfaceMetadataWhenAccomplishValidtion() {
void shouldThrownExceptionWhenTryingToGetNotPreviouslySavedInterface() {
Exception exception = assertThrows(CleverClientException.class,
() -> store.get(ITest.NotSavedService.class));
- assertTrue(exception.getMessage().equals(
- "The interaface NotSavedService has not been saved yet."));
+ assertEquals("The interface NotSavedService has not been saved yet.", exception.getMessage());
}
@Test
void shouldThrownExceptionWhenMethodHasNotHttpAnnotation() {
Exception exception = assertThrows(CleverClientException.class,
() -> store.save(ITest.NotAnnotatedService.class));
- assertTrue(exception.getMessage().equals(
- "Missing HTTP anotation for the method unannotatedMethod."));
+ assertEquals("Missing HTTP annotation for the method unannotatedMethod.",
+ exception.getMessage());
}
@Test
void shouldThrownExceptionWhenUrlPathParamAtMethodUnmatchesAnnotatedArguments() {
Exception exception = assertThrows(CleverClientException.class,
- () -> store.save(ITest.BadPathParamService.class));
- assertTrue(exception.getMessage().equals(
- "Path param demoId in the url cannot find an annotated argument in the method unmatchedPathParamMethod."));
+ () -> store.save(ITest.BadPathParamService.class));
+ assertEquals("Path param demoId in the url cannot find an annotated argument in the method unmatchedPathParamMethod.",
+ exception.getMessage());
}
-}
\ No newline at end of file
+}