Skip to content
This repository was archived by the owner on Jan 31, 2022. It is now read-only.

Commit 732029a

Browse files
Clément Le ProvostPLNech
authored andcommitted
Add support for per-request options (#388)
* feat(request-options): Add support for per-request options WIP: This is an “empty shell” so far: it supports adding untyped headers, but that’s pretty much all. * feat(request-options): Support URL parameters in request options This required a refactoring of the raw request methods to separate the URL parameters (the query string) from the rest of the URL (up to the path). * test(request-options): Add test for URL parameters in request options
1 parent 9fcff0a commit 732029a

File tree

9 files changed

+887
-246
lines changed

9 files changed

+887
-246
lines changed

algoliasearch/src/main/java/com/algolia/search/saas/AbstractClient.java

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -398,28 +398,28 @@ private enum Method {
398398
GET, POST, PUT, DELETE
399399
}
400400

401-
protected byte[] getRequestRaw(String url, boolean search) throws AlgoliaException {
402-
return _requestRaw(Method.GET, url, null, getReadHostsThatAreUp(), connectTimeout, search ? searchTimeout : readTimeout);
401+
protected byte[] getRequestRaw(@NonNull String url, @Nullable Map<String, String> urlParameters, boolean search, @Nullable RequestOptions requestOptions) throws AlgoliaException {
402+
return _requestRaw(Method.GET, url, urlParameters, /* json: */ null, getReadHostsThatAreUp(), connectTimeout, search ? searchTimeout : readTimeout, requestOptions);
403403
}
404404

405-
protected JSONObject getRequest(String url, boolean search) throws AlgoliaException {
406-
return _request(Method.GET, url, null, getReadHostsThatAreUp(), connectTimeout, search ? searchTimeout : readTimeout);
405+
protected JSONObject getRequest(@NonNull String url, @Nullable Map<String, String> urlParameters, boolean search, @Nullable RequestOptions requestOptions) throws AlgoliaException {
406+
return _request(Method.GET, url, urlParameters, /* json: */ null, getReadHostsThatAreUp(), connectTimeout, search ? searchTimeout : readTimeout, requestOptions);
407407
}
408408

409-
protected JSONObject deleteRequest(String url) throws AlgoliaException {
410-
return _request(Method.DELETE, url, null, getWriteHostsThatAreUp(), connectTimeout, readTimeout);
409+
protected JSONObject deleteRequest(@NonNull String url, @Nullable Map<String, String> urlParameters, @Nullable RequestOptions requestOptions) throws AlgoliaException {
410+
return _request(Method.DELETE, url, urlParameters, /* json: */ null, getWriteHostsThatAreUp(), connectTimeout, readTimeout, requestOptions);
411411
}
412412

413-
protected JSONObject postRequest(String url, String obj, boolean readOperation) throws AlgoliaException {
414-
return _request(Method.POST, url, obj, (readOperation ? getReadHostsThatAreUp() : getWriteHostsThatAreUp()), connectTimeout, (readOperation ? searchTimeout : readTimeout));
413+
protected JSONObject postRequest(@NonNull String url, @Nullable Map<String, String> urlParameters, @Nullable String obj, boolean readOperation, @Nullable RequestOptions requestOptions) throws AlgoliaException {
414+
return _request(Method.POST, url, urlParameters, obj, (readOperation ? getReadHostsThatAreUp() : getWriteHostsThatAreUp()), connectTimeout, (readOperation ? searchTimeout : readTimeout), requestOptions);
415415
}
416416

417-
protected byte[] postRequestRaw(String url, String obj, boolean readOperation) throws AlgoliaException {
418-
return _requestRaw(Method.POST, url, obj, (readOperation ? getReadHostsThatAreUp() : getWriteHostsThatAreUp()), connectTimeout, (readOperation ? searchTimeout : readTimeout));
417+
protected byte[] postRequestRaw(@NonNull String url, @Nullable Map<String, String> urlParameters, @Nullable String obj, boolean readOperation, @Nullable RequestOptions requestOptions) throws AlgoliaException {
418+
return _requestRaw(Method.POST, url, urlParameters, obj, (readOperation ? getReadHostsThatAreUp() : getWriteHostsThatAreUp()), connectTimeout, (readOperation ? searchTimeout : readTimeout), requestOptions);
419419
}
420420

421-
protected JSONObject putRequest(String url, String obj) throws AlgoliaException {
422-
return _request(Method.PUT, url, obj, getWriteHostsThatAreUp(), connectTimeout, readTimeout);
421+
protected JSONObject putRequest(@NonNull String url, @Nullable Map<String, String> urlParameters, @NonNull String obj, @Nullable RequestOptions requestOptions) throws AlgoliaException {
422+
return _request(Method.PUT, url, urlParameters, obj, getWriteHostsThatAreUp(), connectTimeout, readTimeout, requestOptions);
423423
}
424424

425425
/**
@@ -482,17 +482,18 @@ private static JSONObject _getAnswerJSONObject(InputStream istream) throws IOExc
482482
* Send the query according to parameters and returns its result as a JSONObject
483483
*
484484
* @param m HTTP Method to use
485-
* @param url endpoint URL
485+
* @param url Endpoint URL, *without query string*. The query string is handled by `urlParameters`.
486+
* @param urlParameters URL parameters
486487
* @param json optional JSON Object to send
487488
* @param hostsArray array of hosts to try successively
488489
* @param connectTimeout maximum wait time to open connection
489490
* @param readTimeout maximum time to read data on socket
490491
* @return a JSONObject containing the resulting data or error
491492
* @throws AlgoliaException if the request data is not valid json
492493
*/
493-
private JSONObject _request(Method m, String url, String json, List<String> hostsArray, int connectTimeout, int readTimeout) throws AlgoliaException {
494+
private JSONObject _request(@NonNull Method m, @NonNull String url, @Nullable Map<String, String> urlParameters, @Nullable String json, @NonNull List<String> hostsArray, int connectTimeout, int readTimeout, @Nullable RequestOptions requestOptions) throws AlgoliaException {
494495
try {
495-
return _getJSONObject(_requestRaw(m, url, json, hostsArray, connectTimeout, readTimeout));
496+
return _getJSONObject(_requestRaw(m, url, urlParameters, json, hostsArray, connectTimeout, readTimeout, requestOptions));
496497
} catch (JSONException e) {
497498
throw new AlgoliaException("JSON decode error:" + e.getMessage());
498499
} catch (UnsupportedEncodingException e) {
@@ -504,15 +505,16 @@ private JSONObject _request(Method m, String url, String json, List<String> host
504505
* Send the query according to parameters and returns its result as a JSONObject
505506
*
506507
* @param m HTTP Method to use
507-
* @param url endpoint URL
508-
* @param json optional JSON Object to send
508+
* @param url Endpoint URL, *without query string*. The query string is handled by `urlParameters`.
509+
* @param urlParameters URL parameters
510+
* @param json (optional) JSON body
509511
* @param hostsArray array of hosts to try successively
510512
* @param connectTimeout maximum wait time to open connection
511513
* @param readTimeout maximum time to read data on socket
512514
* @return a JSONObject containing the resulting data or error
513515
* @throws AlgoliaException in case of connection or data handling error
514516
*/
515-
private byte[] _requestRaw(Method m, String url, String json, List<String> hostsArray, int connectTimeout, int readTimeout) throws AlgoliaException {
517+
private byte[] _requestRaw(@NonNull Method m, @NonNull String url, @Nullable Map<String, String> urlParameters, @Nullable String json, @NonNull List<String> hostsArray, int connectTimeout, int readTimeout, @Nullable RequestOptions requestOptions) throws AlgoliaException {
516518
String requestMethod;
517519
List<Exception> errors = new ArrayList<>(hostsArray.size());
518520
// for each host
@@ -536,17 +538,32 @@ private byte[] _requestRaw(Method m, String url, String json, List<String> hosts
536538

537539
InputStream stream = null;
538540
HttpURLConnection hostConnection = null;
539-
// set URL
540541
try {
541-
URL hostURL = new URL("https://" + host + url);
542+
// Compute final URL parameters.
543+
final Map<String, String> parameters = new HashMap<>();
544+
if (urlParameters != null) {
545+
parameters.putAll(urlParameters);
546+
}
547+
if (requestOptions != null) {
548+
parameters.putAll(requestOptions.urlParameters);
549+
}
550+
551+
// Build URL.
552+
String urlString = "https://" + host + url;
553+
if (!parameters.isEmpty()) {
554+
urlString += "?" + AbstractQuery.build(parameters);
555+
}
556+
URL hostURL = new URL(urlString);
557+
558+
// Open connection.
542559
hostConnection = (HttpURLConnection) hostURL.openConnection();
543560

544561
//set timeouts
545562
hostConnection.setRequestMethod(requestMethod);
546563
hostConnection.setConnectTimeout(connectTimeout);
547564
hostConnection.setReadTimeout(readTimeout);
548565

549-
// set auth headers
566+
// Headers
550567
hostConnection.setRequestProperty("X-Algolia-Application-Id", this.applicationID);
551568
// If API key is too big, send it in the request's body (if applicable).
552569
if (this.apiKey != null && this.apiKey.length() > MAX_API_KEY_LENGTH && json != null) {
@@ -560,9 +577,16 @@ private byte[] _requestRaw(Method m, String url, String json, List<String> hosts
560577
} else {
561578
hostConnection.setRequestProperty("X-Algolia-API-Key", this.apiKey);
562579
}
580+
// Client-level headers
563581
for (Map.Entry<String, String> entry : this.headers.entrySet()) {
564582
hostConnection.setRequestProperty(entry.getKey(), entry.getValue());
565583
}
584+
// Request-level headers
585+
if (requestOptions != null) {
586+
for (Map.Entry<String, String> entry : requestOptions.headers.entrySet()) {
587+
hostConnection.setRequestProperty(entry.getKey(), entry.getValue());
588+
}
589+
}
566590

567591
// set user agent
568592
hostConnection.setRequestProperty("User-Agent", userAgentRaw);

algoliasearch/src/main/java/com/algolia/search/saas/AbstractQuery.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ public int hashCode() {
113113
// NOTE: Using a tree map to have parameters sorted by key on output.
114114
@NonNull private Map<String, String> parameters = new TreeMap<>();
115115

116+
/**
117+
* Access the store of query parameters. For internal use only.
118+
* @return The parameters in this query.
119+
*/
120+
Map<String, String> getParameters() {
121+
return parameters;
122+
}
123+
116124
// ----------------------------------------------------------------------
117125
// Construction
118126
// ----------------------------------------------------------------------
@@ -167,6 +175,14 @@ public int hashCode() {
167175
* @return A string suitable for use inside the query part of a URL (i.e. after the question mark).
168176
*/
169177
public @NonNull String build() {
178+
return build(parameters);
179+
}
180+
181+
/**
182+
* Build a query string from a map of URL parameters.
183+
* @return A string suitable for use inside the query part of a URL (i.e. after the question mark).
184+
*/
185+
static @NonNull String build(@NonNull Map<String, String> parameters) {
170186
StringBuilder stringBuilder = new StringBuilder();
171187
try {
172188
for (Map.Entry<String, String> entry : parameters.entrySet()) {

0 commit comments

Comments
 (0)