Skip to content

Commit a77c544

Browse files
committed
Support RecommendNextItems endpoint
1 parent 56c0fcf commit a77c544

File tree

130 files changed

+629
-534
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

130 files changed

+629
-534
lines changed

README.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ The client is available in the [Maven Central Repository](https://mvnrepository.
1313
<dependency>
1414
<groupId>com.recombee</groupId>
1515
<artifactId>api-client</artifactId>
16-
<version>3.0.0</version>
16+
<version>3.1.0</version>
1717
</dependency>
1818
```
1919

@@ -40,7 +40,7 @@ public class BasicExample {
4040

4141
RecombeeClient client = new RecombeeClient("--my-database-id--", "--db-private-token--");
4242
try {
43-
client.send(new ResetDatabase());
43+
4444
final int NUM = 100;
4545
// Generate some random purchases of items by users
4646
final double PROBABILITY_PURCHASED = 0.1;
@@ -64,6 +64,11 @@ public class BasicExample {
6464
System.out.println("Recommended items:");
6565
for(Recommendation rec: recommendationResponse) System.out.println(rec.getId());
6666

67+
// User scrolled down - get next 3 recommended items
68+
recommendationResponse = client.send(new RecommendNextItems(recommendationResponse.getRecommId(), 3));
69+
System.out.println("Next recommended items:");
70+
for(Recommendation rec: recommendationResponse) System.out.println(rec.getId());
71+
6772
} catch (ApiException e) {
6873
e.printStackTrace();
6974
//use fallback

pom.xml

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.recombee</groupId>
88
<artifactId>api-client</artifactId>
9-
<version>3.0.0</version>
9+
<version>3.1.0</version>
1010
<name>Recombee API Client</name>
1111
<description>A client library for easy use of the Recombee recommendation API</description>
1212
<url>http://recombee.com</url>
@@ -45,17 +45,17 @@
4545
<dependency>
4646
<groupId>com.fasterxml.jackson.core</groupId>
4747
<artifactId>jackson-core</artifactId>
48-
<version>2.9.10</version>
48+
<version>2.12.1</version>
4949
</dependency>
5050
<dependency>
5151
<groupId>com.fasterxml.jackson.core</groupId>
5252
<artifactId>jackson-databind</artifactId>
53-
<version>2.9.10.1</version>
53+
<version>2.12.1</version>
5454
</dependency>
5555
<dependency>
5656
<groupId>junit</groupId>
5757
<artifactId>junit</artifactId>
58-
<version>4.12</version>
58+
<version>4.13.1</version>
5959
</dependency>
6060
<dependency>
6161
<groupId>commons-lang</groupId>

src/main/java/com/recombee/api_client/RecombeeClient.java

+37-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.recombee.api_client;
22

33
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.DeserializationFeature;
45
import com.fasterxml.jackson.databind.ObjectMapper;
56
import com.fasterxml.jackson.core.type.TypeReference;
67

@@ -64,8 +65,9 @@
6465
import com.recombee.api_client.api_requests.ListItemViewPortions;
6566
import com.recombee.api_client.api_requests.ListUserViewPortions;
6667
import com.recombee.api_client.api_requests.RecommendItemsToUser;
67-
import com.recombee.api_client.api_requests.RecommendUsersToUser;
6868
import com.recombee.api_client.api_requests.RecommendItemsToItem;
69+
import com.recombee.api_client.api_requests.RecommendNextItems;
70+
import com.recombee.api_client.api_requests.RecommendUsersToUser;
6971
import com.recombee.api_client.api_requests.RecommendUsersToItem;
7072
import com.recombee.api_client.api_requests.SearchItems;
7173
import com.recombee.api_client.api_requests.UserBasedRecommendation;
@@ -86,7 +88,7 @@ public class RecombeeClient {
8688

8789
final int BATCH_MAX_SIZE = 10000; //Maximal number of requests within one batch request
8890

89-
final String USER_AGENT = "recombee-java-api-client/3.0.0";
91+
final String USER_AGENT = "recombee-java-api-client/3.1.0";
9092

9193
private final OkHttpClient httpClient = new OkHttpClient();
9294

@@ -96,6 +98,7 @@ public RecombeeClient(String databaseId, String token) {
9698
this.mapper = new ObjectMapper();
9799
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
98100
this.mapper.setDateFormat(df);
101+
this.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
99102

100103
if (System.getenv("RAPI_URI") != null)
101104
this.baseUri = System.getenv("RAPI_URI");
@@ -325,7 +328,7 @@ public RecommendationResponse send(RecommendItemsToUser request) throws ApiExcep
325328
return null;
326329
}
327330

328-
public RecommendationResponse send(RecommendUsersToUser request) throws ApiException {
331+
public RecommendationResponse send(RecommendItemsToItem request) throws ApiException {
329332
String responseStr = sendRequest(request);
330333
try {
331334
return this.mapper.readValue(responseStr, RecommendationResponse.class);
@@ -335,7 +338,17 @@ public RecommendationResponse send(RecommendUsersToUser request) throws ApiExcep
335338
return null;
336339
}
337340

338-
public RecommendationResponse send(RecommendItemsToItem request) throws ApiException {
341+
public RecommendationResponse send(RecommendNextItems request) throws ApiException {
342+
String responseStr = sendRequest(request);
343+
try {
344+
return this.mapper.readValue(responseStr, RecommendationResponse.class);
345+
} catch (IOException e) {
346+
e.printStackTrace();
347+
}
348+
return null;
349+
}
350+
351+
public RecommendationResponse send(RecommendUsersToUser request) throws ApiException {
339352
String responseStr = sendRequest(request);
340353
try {
341354
return this.mapper.readValue(responseStr, RecommendationResponse.class);
@@ -452,7 +465,8 @@ else if (request instanceof ListUsers)
452465
else if ((request instanceof RecommendItemsToUser) ||
453466
(request instanceof RecommendUsersToUser) ||
454467
(request instanceof RecommendItemsToItem) ||
455-
(request instanceof RecommendUsersToItem))
468+
(request instanceof RecommendUsersToItem) ||
469+
(request instanceof RecommendNextItems))
456470
{
457471
parsedResponse = mapper.convertValue(parsedResponse, RecommendationResponse.class);
458472
}
@@ -714,6 +728,7 @@ protected Recommendation[] sendDeprecatedRecomm(Request request) throws ApiExcep
714728
String responseStr = sendRequest(request);
715729

716730
try {
731+
this.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); // Check exact match
717732
return this.mapper.readValue(responseStr, Recommendation[].class);
718733
} catch (IOException e) {
719734
//might have failed because it returned also the item properties
@@ -728,14 +743,18 @@ protected Recommendation[] sendDeprecatedRecomm(Request request) throws ApiExcep
728743
} catch (IOException e2) {
729744
e2.printStackTrace();
730745
}
731-
}
732-
return null;
746+
}
747+
finally {
748+
this.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
749+
}
750+
return null;
733751
}
734752

735753
public Item[] send(ListItems request) throws ApiException {
736754
String responseStr = sendRequest(request);
737755

738756
try {
757+
this.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); // Check exact match
739758
return this.mapper.readValue(responseStr, Item[].class);
740759
} catch (IOException e) {
741760
//might have failed because it returned also the item properties
@@ -750,15 +769,19 @@ public Item[] send(ListItems request) throws ApiException {
750769
} catch (IOException e2) {
751770
e2.printStackTrace();
752771
}
753-
}
754-
return null;
772+
}
773+
finally {
774+
this.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
775+
}
776+
return null;
755777
}
756778

757779

758780
public User[] send(ListUsers request) throws ApiException {
759781
String responseStr = sendRequest(request);
760782

761783
try {
784+
this.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); // Check exact match
762785
return this.mapper.readValue(responseStr, User[].class);
763786
} catch (IOException e) {
764787
//might have failed because it returned also the user properties
@@ -773,8 +796,11 @@ public User[] send(ListUsers request) throws ApiException {
773796
} catch (IOException e2) {
774797
e2.printStackTrace();
775798
}
776-
}
777-
return null;
799+
}
800+
finally {
801+
this.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
802+
}
803+
return null;
778804
}
779805

780806
public String send(Request request) throws ApiException {

src/main/java/com/recombee/api_client/api_requests/RecommendItemsToItem.java

+14-7
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@
1313

1414
/**
1515
* Recommends set of items that are somehow related to one given item, *X*. Typical scenario is when user *A* is viewing *X*. Then you may display items to the user that he might be also interested in. Recommend items to item request gives you Top-N such items, optionally taking the target user *A* into account.
16+
* The returned items are sorted by relevance (first item being the most relevant).
17+
* Besides the recommended items, also a unique `recommId` is returned in the response. It can be used to:
18+
* - Let Recombee know that this recommendation was successful (e.g. user clicked one of the recommended items). See [Reported metrics](https://docs.recombee.com/admin_ui.html#reported-metrics).
19+
* - Get subsequent recommended items when the user scrolls down (*infinite scroll*) or goes to the next page. See [Recommend Next Items](https://docs.recombee.com/api.html#recommend-next-items).
1620
* It is also possible to use POST HTTP method (for example in case of very long ReQL filter) - query parameters then become body parameters.
17-
* The returned items are sorted by relevancy (first item being the most relevant).
1821
*/
1922
public class RecommendItemsToItem extends Request {
2023

@@ -78,7 +81,8 @@ public class RecommendItemsToItem extends Request {
7881
* "url": "myshop.com/mixer-42"
7982
* }
8083
* }
81-
* ]
84+
* ],
85+
* "numberNextRecommsCalls": 0
8286
* }
8387
* ```
8488
*/
@@ -105,7 +109,8 @@ public class RecommendItemsToItem extends Request {
105109
* "price": 39
106110
* }
107111
* }
108-
* ]
112+
* ],
113+
* "numberNextRecommsCalls": 0
109114
* }
110115
* ```
111116
*/
@@ -136,7 +141,7 @@ public class RecommendItemsToItem extends Request {
136141
*/
137142
protected Double diversity;
138143
/**
139-
* **Expert option** If the *targetUserId* is provided: Specifies the threshold of how much relevant must the recommended items be to the user. Possible values one of: "low", "medium", "high". The default value is "low", meaning that the system attempts to recommend number of items equal to *count* at any cost. If there are not enough data (such as interactions or item properties), this may even lead to bestseller-based recommendations to be appended to reach the full *count*. This behavior may be suppressed by using "medium" or "high" values. In such case, the system only recommends items of at least the requested relevancy, and may return less than *count* items when there is not enough data to fulfill it.
144+
* **Expert option** If the *targetUserId* is provided: Specifies the threshold of how much relevant must the recommended items be to the user. Possible values one of: "low", "medium", "high". The default value is "low", meaning that the system attempts to recommend number of items equal to *count* at any cost. If there are not enough data (such as interactions or item properties), this may even lead to bestseller-based recommendations to be appended to reach the full *count*. This behavior may be suppressed by using "medium" or "high" values. In such case, the system only recommends items of at least the requested relevance, and may return less than *count* items when there is not enough data to fulfill it.
140145
*/
141146
protected String minRelevance;
142147
/**
@@ -225,7 +230,8 @@ public RecommendItemsToItem setCascadeCreate(boolean cascadeCreate) {
225230
* "url": "myshop.com/mixer-42"
226231
* }
227232
* }
228-
* ]
233+
* ],
234+
* "numberNextRecommsCalls": 0
229235
* }
230236
* ```
231237
*/
@@ -256,7 +262,8 @@ public RecommendItemsToItem setReturnProperties(boolean returnProperties) {
256262
* "price": 39
257263
* }
258264
* }
259-
* ]
265+
* ],
266+
* "numberNextRecommsCalls": 0
260267
* }
261268
* ```
262269
*/
@@ -311,7 +318,7 @@ public RecommendItemsToItem setDiversity(double diversity) {
311318
}
312319

313320
/**
314-
* @param minRelevance **Expert option** If the *targetUserId* is provided: Specifies the threshold of how much relevant must the recommended items be to the user. Possible values one of: "low", "medium", "high". The default value is "low", meaning that the system attempts to recommend number of items equal to *count* at any cost. If there are not enough data (such as interactions or item properties), this may even lead to bestseller-based recommendations to be appended to reach the full *count*. This behavior may be suppressed by using "medium" or "high" values. In such case, the system only recommends items of at least the requested relevancy, and may return less than *count* items when there is not enough data to fulfill it.
321+
* @param minRelevance **Expert option** If the *targetUserId* is provided: Specifies the threshold of how much relevant must the recommended items be to the user. Possible values one of: "low", "medium", "high". The default value is "low", meaning that the system attempts to recommend number of items equal to *count* at any cost. If there are not enough data (such as interactions or item properties), this may even lead to bestseller-based recommendations to be appended to reach the full *count*. This behavior may be suppressed by using "medium" or "high" values. In such case, the system only recommends items of at least the requested relevance, and may return less than *count* items when there is not enough data to fulfill it.
315322
*/
316323
public RecommendItemsToItem setMinRelevance(String minRelevance) {
317324
this.minRelevance = minRelevance;

src/main/java/com/recombee/api_client/api_requests/RecommendItemsToUser.java

+14-7
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@
1414
/**
1515
* Based on user's past interactions (purchases, ratings, etc.) with the items, recommends top-N items that are most likely to be of high value for a given user.
1616
* The most typical use cases are recommendations at homepage, in some "Picked just for you" section or in email.
17+
* The returned items are sorted by relevance (first item being the most relevant).
18+
* Besides the recommended items, also a unique `recommId` is returned in the response. It can be used to:
19+
* - Let Recombee know that this recommendation was successful (e.g. user clicked one of the recommended items). See [Reported metrics](https://docs.recombee.com/admin_ui.html#reported-metrics).
20+
* - Get subsequent recommended items when the user scrolls down (*infinite scroll*) or goes to the next page. See [Recommend Next Items](https://docs.recombee.com/api.html#recommend-next-items).
1721
* It is also possible to use POST HTTP method (for example in case of very long ReQL filter) - query parameters then become body parameters.
18-
* The returned items are sorted by relevancy (first item being the most relevant).
1922
*/
2023
public class RecommendItemsToUser extends Request {
2124

@@ -63,7 +66,8 @@ public class RecommendItemsToUser extends Request {
6366
* "url": "myshop.com/mixer-42"
6467
* }
6568
* }
66-
* ]
69+
* ],
70+
* "numberNextRecommsCalls": 0
6771
* }
6872
* ```
6973
*/
@@ -90,7 +94,8 @@ public class RecommendItemsToUser extends Request {
9094
* "price": 39
9195
* }
9296
* }
93-
* ]
97+
* ],
98+
* "numberNextRecommsCalls": 0
9499
* }
95100
* ```
96101
*/
@@ -117,7 +122,7 @@ public class RecommendItemsToUser extends Request {
117122
*/
118123
protected Double diversity;
119124
/**
120-
* **Expert option** Specifies the threshold of how much relevant must the recommended items be to the user. Possible values one of: "low", "medium", "high". The default value is "low", meaning that the system attempts to recommend number of items equal to *count* at any cost. If there are not enough data (such as interactions or item properties), this may even lead to bestseller-based recommendations to be appended to reach the full *count*. This behavior may be suppressed by using "medium" or "high" values. In such case, the system only recommends items of at least the requested relevancy, and may return less than *count* items when there is not enough data to fulfill it.
125+
* **Expert option** Specifies the threshold of how much relevant must the recommended items be to the user. Possible values one of: "low", "medium", "high". The default value is "low", meaning that the system attempts to recommend number of items equal to *count* at any cost. If there are not enough data (such as interactions or item properties), this may even lead to bestseller-based recommendations to be appended to reach the full *count*. This behavior may be suppressed by using "medium" or "high" values. In such case, the system only recommends items of at least the requested relevance, and may return less than *count* items when there is not enough data to fulfill it.
121126
*/
122127
protected String minRelevance;
123128
/**
@@ -192,7 +197,8 @@ public RecommendItemsToUser setCascadeCreate(boolean cascadeCreate) {
192197
* "url": "myshop.com/mixer-42"
193198
* }
194199
* }
195-
* ]
200+
* ],
201+
* "numberNextRecommsCalls": 0
196202
* }
197203
* ```
198204
*/
@@ -223,7 +229,8 @@ public RecommendItemsToUser setReturnProperties(boolean returnProperties) {
223229
* "price": 39
224230
* }
225231
* }
226-
* ]
232+
* ],
233+
* "numberNextRecommsCalls": 0
227234
* }
228235
* ```
229236
*/
@@ -270,7 +277,7 @@ public RecommendItemsToUser setDiversity(double diversity) {
270277
}
271278

272279
/**
273-
* @param minRelevance **Expert option** Specifies the threshold of how much relevant must the recommended items be to the user. Possible values one of: "low", "medium", "high". The default value is "low", meaning that the system attempts to recommend number of items equal to *count* at any cost. If there are not enough data (such as interactions or item properties), this may even lead to bestseller-based recommendations to be appended to reach the full *count*. This behavior may be suppressed by using "medium" or "high" values. In such case, the system only recommends items of at least the requested relevancy, and may return less than *count* items when there is not enough data to fulfill it.
280+
* @param minRelevance **Expert option** Specifies the threshold of how much relevant must the recommended items be to the user. Possible values one of: "low", "medium", "high". The default value is "low", meaning that the system attempts to recommend number of items equal to *count* at any cost. If there are not enough data (such as interactions or item properties), this may even lead to bestseller-based recommendations to be appended to reach the full *count*. This behavior may be suppressed by using "medium" or "high" values. In such case, the system only recommends items of at least the requested relevance, and may return less than *count* items when there is not enough data to fulfill it.
274281
*/
275282
public RecommendItemsToUser setMinRelevance(String minRelevance) {
276283
this.minRelevance = minRelevance;

0 commit comments

Comments
 (0)