# cloud-rest-api-client
**Repository Path**: wxb1983/cloud-rest-api-client
## Basic Information
- **Project Name**: cloud-rest-api-client
- **Description**: No description available
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2022-02-07
- **Last Updated**: 2022-02-07
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# REST API Client Library
[](https://api.reuse.software/info/github.com/SAP/cloud-rest-api-client)
Java HTTP client library for HTTP handling, when building clients for RESTful APIs.
## Prerequisities and Dependencies
- Java 8
- [Apache HTTP Client](https://hc.apache.org/httpcomponents-client-ga/index.html)
- [Jackson Faster XML](https://github.com/FasterXML/jackson)
- [Apache Commons Lang](https://commons.apache.org/proper/commons-lang/)
## Installation
Build the library using the following maven command.
```
mvn clean install
```
## Executing Unit Tests
The unit tests of the library can be executed with the following Maven command
```
mvn clean install -Punit-tests
```
# Usage
Add the following dependency to your maven __pom.xml__ file.
```
com.sap.cloud.client
rest-api-client
${latest.version}
```
## Creating a RestApiClient
To create a Rest API Client, you need to extend the __RestApiClient__ class and construct it by passing a __RestApiClientConfig__ to it.
```java
public class DefaultRestApiClient extends RestApiClient {
private static final String API_PATH = "/api";
public DefaultRestApiClient(RestApiClientConfig restApiClientConfig) {
super(restApiClientConfig);
}
@Override
protected String getApiPath() {
return API_PATH;
}
}
```
## Using a Custom HttpClientProvider
An __HttpClientProvider__ is an interface with one method ```HttpClient createHttpClient()```.
The __HttpClient__ returned by this method is used for executing requests in __RestApiClient__. By default, an __HttpClientProviderFactory__ creates default __HttpClientProvider__ implementations depending on the __AuthenticationType__ found in ```restApiClientConfig```.
__RestApiClient__ has a constructor where a custom implementation can be provided, to override the default http clients used.
```java
public DefaultRestApiClient(RestApiClientConfig restApiClientConfig, HttpClientProvider httpClientProvider) {
super(restApiClientConfig, httpClientProvider);
}
```
## Creating a RestApiClientConfig
__RestApiClientConfig__ has a host and an object of type __Authentication__. You can construct it using ```RestApiClientConfigBuilder.getBuilder()``` to get an instance of the __RestApiClientConfigBuilder__. Supported authentication types are __ClientCertAuthentication__, __BasicAuthentication__, __OAuthAuthentication__ and __NoAuthentication__. It also supports configuring a proxy that will be used in the __RestApiClient__.
### No Authentication
```java
RestApiClientConfig config = RestApiClientConfigBuilder.getBuilder()
.host()
.authentication(new NoAuthentication())
.build();
```
You can also use the utility method for No Authentication.
```java
RestApiClientConfig config = RestApiClientConfigBuilder.getBuilder()
.host()
.noAuthentication()
.build();
```
You could also skip the ```noAuthentication()``` method. __RestApiClientConfigBuilder__ constructs configurations with no authentication by default.
```java
RestApiClientConfig config = RestApiClientConfigBuilder.getBuilder()
.host()
.build();
```
### Basic Authentication
To use basic authentication, you have to provide a username and password.
```java
RestApiClientConfig config = RestApiClientConfigBuilder.getBuilder()
.host()
.authentication(new BasicAuthentication(, ))
.build();
```
You can also use the utility method for Basic Authentication.
```java
RestApiClientConfig config = RestApiClientConfigBuilder.getBuilder()
.host()
.basicAuthentication(, )
.build();
```
### Client Certificate Authentication
To use the client certificate authentication, you have to provide a __KeystoreConfig__. You can construct it using ```KeystoreConfigBuilder.getBuilder()``` to get an instance of the __KeystoreConfigBuilder__.
```java
KeyStore keystore; // initialize with your keystore
KeystoreConfig keystoreConfig = KeystoreConfigBuilder.getBuilder()
.keystore(keystore)
.keystorePassword("")
.keyAlias("")
.build();
RestApiClientConfig config = RestApiClientConfigBuilder.getBuilder()
.host()
.authentication(new ClientCertAuthentication(keystoreConfig))
.build();
```
You can also use the utility method for Client Certificate Authentication.
```java
RestApiClientConfig config = RestApiClientConfigBuilder.getBuilder()
.host()
.clientCertAuthentication(keystoreConfig)
.build();
```
__Note__: By default, the __SSLHttpClientProvider__ returned from __HttpClientProviderFactory__ creates an http client with connection timeout of 30 seconds (30000 milliseconds). To configure the timeout, create an __SSLHttpClientProvider__ with a custom timeout (in milliseconds) and pass it to the __RestApiClient__ constructor.
```java
KeystoreConfig keystoreConfig; // initialize as above
RestApiClientConfig config; // initialize as above
ClientCertAuthentication authentication = new ClientCertAuthentication(keystoreConfig);
SSLHttpClientProvider clientProvider = new SSLHttpClientProvider(authentication, );
RestApiClient restApiClient = new DefaultRestApiClient(config, clientProvider);
```
### OAuth Authentication
To use OAuth authentication you have to provide an __OAuthServerConfig__. It is used for requesting access tokens. You can construct it using ```OAuthServerConfigBuilder.getBuilder()``` to get an instance of the __OAuthServerConfigBuilder__
```java
OAuthServerConfig oAuthServerConfig = OAuthServerConfigBuilder.getBuilder()
.oAuthServerHost() // e.g https://authentication.sap.hana.ondemand.com
.clientID()
.clientSecret("".toCharArray())
.build();
RestApiClientConfig config = RestApiClientConfigBuilder.getBuilder()
.host("")
.authentication(new OAuthAuthentication(oAuthServerConfig))
.build();
```
You can also use the utility method for OAuth Authentication.
```java
RestApiClientConfig config = RestApiClientConfigBuilder.getBuilder()
.host("")
.oauthAuthentication(oAuthServerConfig)
.build();
```
__Note__: By default, the __OAuthServerConfigBuilder__ creates a configuration with an API path ```/oauth/token```. If the path of the server is different, you can set it explicitly with the ```oAuthServerApiPath("")``` method. For example, the access token endpoint for Neo currently has an API path of ```/oauth2/api/v1/token```.
__Note__: By default, the __OAuthServerConfigBuilder__ creates a configuration with an OAuth Header key ```Authorization```. If the header key you want to set the Bearer header on is different, you can set it explicitly with the ```oAuthHeaderKey("")``` method.
### Configuring a Proxy
To set up a proxy for the __RestApiClient__, pass a __Proxy__ object to the __RestApiClientConfig__. The __Proxy__ object consists of hostname, port and scheme.
```java
Proxy proxy = new Proxy("", 8888, "https"); //Represents a proxy with host https://:8888
```
If the scheme is not provided, it is ```http``` by default.
```java
Proxy proxy = new Proxy("", 8888); //Represents a proxy with host http://:8888
```
Then attach the created __Proxy__ to the __RestApiClientConfigBuilder__. When building the configuration, the builder will create an __HttpRoutePlanner__, using the __Proxy__ object. This route planner will be set to the __HttpClient__ that is internally used in the __RestApiClient__.
```java
RestApiClientConfig config = RestApiClientConfigBuilder.getBuilder()
.host("")
.proxy(proxy)
.build();
```
The __RestApiClientConfigBuilder__ also supports directly passing an __HttpRoutePlanner__ to the proxy method.
```java
HttpHost httpHost = new HttpHost("", 8888, "http");
HttpRoutePlanner httpRoutePlanner = new DefaultProxyRoutePlanner(httpHost);
RestApiClientConfig config = RestApiClientConfigBuilder.getBuilder()
.host("")
.proxy(httpRoutePlanner)
.build();
```
## Using the RestApiClient
To execute a request with __RestApiClient__ you have to build a __Request__ object and call the ```Response execute(Request request)``` method.
__Request__ is a generic class that consists of an __HttpUriRequest__ and an entity representing the request body. It can be constructed using the provided __RequestBuilder__. Passing a URI is obligatory. It support deserialization of objects to JSON using the Jackson library. It also supports multipart requests.
Initialize the builder with one of its static methods.
```java
Request request = RequestBuilder
.getRequest()
.uri()
.addParameter(, )
.addHeader(, )
.build();
client.execute(testEntityRequest);
```
To use the deserialization , pass a __Class__ object of the type you will deserialize and pass an object of this type to the ```entity(T entity)``` method.
```java
TestEntity testEntity = new TestEntity();
Request testEntityRequest = RequestBuilder
.postRequest(TestEntity.class)
.uri()
.entity(testEntity)
.build();
client.execute(testEntityRequest);
```
To build a multipart request, add entity parts with the ```multipartEntity(String name, T entity)``` method and build the __Request__ with ```buildMultipart()``` instead of ```build()```. The created __Request__ object is of type __MultipartEntity__ - a generic model holding all entity parts and their names.
```java
TestEntity testEntityPartOne = new TestEntity();
TestEntity testEntityPartTwo = new TestEntity();
Request> testEntityMultipartRequest = RequestBuilder
.postRequest(TestEntity.class)
.multipartEntity(, testEntityPartOne)
.multipartEntity(, testEntityPartTwo)
.uri()
.buildMultipart();
client.execute(testEntityMultipartRequest);
```
If the __RequestBuilder__ is not suitable to your use case (e.g. lacks functionality), you can directly build an __HttpUriRequest__ and construct the __Request__ object with it using the constructor. Use [org.apache.http.client.methods.RequestBuilder documentation](http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/methods/RequestBuilder.html) for reference.
Note that this approach is not recommended as it leaves the opportunity that the developer does not pass the request entity (if any) to the __Request__ object and miss on the logging that it provides. The following example won't log the request object in case of any errors.
```java
HttpUriRequest httpUriRequest = RequestBuilder.get().build();
Request request = new Request<>(httpUriRequest);
client.execute(request);
```
__RestApiClient__ works with a __StatusCodeHandler__ and can accept a custom implementation. The library provides a default implementation (__DefaultStatusCodeHandler__), which is used if a handler is not explicitly provided. It is handling ```401``` response code by throwing an __UnauthorizedException__ and all other status codes larger than 300 by throwing the generic __ResponseException__. The exceptions provide an __HttpExchangeContext__ object that holds both the __Request__ and __Response__ objects of the request execution.
```java
client.execute(request, customStatusCodeHandler);
```
__RestApiClient__ works with a __org.apache.http.client.ResponseHandler__ to parse the response body and can accept a custom implementation. If no custom implementation is provided, it uses the __DefaultResponseHandler__, which returns the response body as a string. The library provides two utility response handlers that use the Jackson library to deserialize a response into whatever type is provided to them as a generic:
* __JacksonJsonResponseHandler__ deserializes JSON responses.
* __PropertiesResponseHandler__ deserializes properties responses in the format of `property=value`.
```java
client.execute(request, customResponseHandler);
```
You can also provide both a response and a status code handler.
```java
client.execute(request, customResponseHandler, customStatusCodeHandler);
```
__Note:__ The following exceptions are thrown by the interface methods:
* __ConnectionException__ in case of an IOException.
* __ResponseException__ if an error HTTP status code is received.
* __UnauthorizedException__ in case of a 401 Unauthorized response code, if using the default status code handler.
* __RestApiClientException__ is the common exception for all of the above.
# Contribution
We welcome any exchange and collaboration with individuals and organizations interested in the use, support and extension of the library.
# License
Copyright © 2017-2020 SAP SE or an SAP affiliate company. All rights reserved. This project is licensed under the Apache Software License, version 2.0 except as noted otherwise in the [LICENSE file](LICENSES/Apache-2.0.txt).