调用个性化推荐接口,传入用户id以及相关的上下文信息等,可以获得推荐结果列表。
HTTPS POST
《Path内相关变量解释》
/predict/api/${application_id}/default
公共请求头部分详见《公共请求头说明》。
接口额外请求头:
参数 | 说明 | 示例 | 是否必传 |
---|---|---|---|
Enable-Spm-Route | 用于告知推荐服务是否开启SPM路由。开启了之后推荐服务会根据请求携带的SPM将请求路由到绑定的栏位处理逻辑中。开启SPM路由的时候需要确保请求中的SPM是有效的SPM,且已经绑定了栏位。否则服务端会返回错误。 | true | 是 |
参数
参数 | 类型 | 是否必传 | 描述 |
---|---|---|---|
user | object | 是 | 用户信息。 |
context | object | 是 | 上下文信息。 |
candidateItems | object list | 否 | 跳过召回等特殊场景需要上传候选集。 |
parentItem | object | 否 | 相关推荐场景需要上传。 |
filterItems | object list | 否 | 需要过滤的物品列表。 |
size | int | 否 | 接口返回物品个数(优先级高于栏位配置返回数量) |
示例
{ "user":{ "uid":"uid1", "device":{ "deviceId":"device_id", "platform":"ios" }, "age":"30", "gender":"male", "province":"GuangDong", "city":"ShenZhen", "country":"China" }, "context":{ "spm":"A$##$B$##$C", "feature":{ "stringFeature":{ "key":"value" }, "intFeature":{ "key":2 }, "floatFeature":{ "key":3.5 }, "doubleFeature":{ "key":3.51231 }, "stringArrayFeature":{ "key":{ "values":[ "values1", "values2" ] } }, "intArrayFeature":{ "key":{ "values":[ 1, 2 ] } }, "floatArrayFeature":{ "key":{ "values":[ 1.1, 2.2 ] } }, "doubleArrayFeature":{ "key":{ "values":[ 1.11111, 2.22222 ] } } }, "filter":{ "stringFilter":{ "key":"value" }, "intFilter":{ "key":2 }, "floatFilter":{ "key":3.5 }, "doubleFilter":{ "key":3.51231 }, "stringArrayFilter":{ "key":{ "values":[ "value1", "value2" ] } }, "intArrayFilter":{ "key":{ "values":[ 1, 2 ] } }, "floatArrayFilter":{ "key":{ "values":[ 1.1, 2.2 ] } }, "doubleArrayFilter":{ "key":{ "values":[ 1.11111, 2.22222 ] } } }, "extra":{ "key1":"value1", "key2":"value2" } }, "candidateItems":[ { "id":"item_id1" }, { "id":"item_id2" } ], "parentItem":{ "id":"item_id3" }, "filterItems":[ { "id":"item_id4" }, { "id":"item_id5" } ], "size":10 }
参数
参数 | 类型 | 描述 |
---|---|---|
code | int32 | 不等同于http status,用于排查业务错误。200代表正常。非200代表错误。 |
message | string | 状态信息,默认"OK",遇到错误会返回错误信息。 |
value | object | |
request_id | string | 推荐请求的requestId。 |
success | bool | success字段存在,且等于true的时候,请求才是成功的。含义比code更简单直接一些。 |
示例
{ "code":200, "message":"OK", "value":{ "items":[ { "id":"12345789", "rank":1, "transData":"jJGJveDUifbABAMoBDHRlc3RfZ2FubGluMQ==", "extra":{ "score":"0.67912" } }, { "id":"56479201", "rank":2, "transData":"25vbGl0aBUa4MW/jhjkdsa+kljlkjdsa==", "extra":{ "score":"0.45213" } }, { "id":"12340987", "rank":3, "transData":"dsjkahiunfmn1231/dsafkl+23123adaasd==", "extra":{ "score":"0.33768" } } ] }, "request_id":"sfbnbm-123sam-dsajkh", "success":true }
import com.alibaba.fastjson2.JSON; import okhttp3.*; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.*; public class Main { final static String token = "xxx"; // 替换为实际的token final static String tenantId = "xxx"; // 替换为实际的租户id final static String applicationId = "xxx"; // 替换为实际的应用id final static String predictUrl = "https://api.byteair.volces.com/predict/api/" + applicationId + "/default"; public static void main(String[] args) { predict(); } public static void predict() { String tenantTs = Integer.toString((int) (System.currentTimeMillis() / 1000)); // 当前时间戳 String tenantNonce = UUID.randomUUID().toString().substring(0, 8); // 随机字符串 byte[] httpBody = JSON.toJSONBytes(new HashMap<>() {{ // 示例用http body.真实请求请替换成实际使用的body. put("user", new HashMap<>() {{ put("uid", "123"); }}); put("context", new HashMap<>() {{ put("spm", "1$##$2$##$3"); }}); }}); String sign = calSignature(token, tenantId, tenantTs, tenantNonce, httpBody); Headers.Builder builder = createHeader(tenantTs, tenantNonce, sign); builder.set("Enable-Spm-Route", "true"); System.out.println(builder.build().toString()); System.out.println(new String(httpBody)); Request request = new Request.Builder() .url(predictUrl) .headers(builder.build()) .post(RequestBody.create(httpBody)) .build(); OkHttpClient client = new OkHttpClient(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { System.out.println("action=predict`phase=failure"); } @Override public void onResponse(Call call, Response response) throws IOException { String body = response.body().string(); System.out.println(body); } }); } //根据token、tenant_id、tenantTs、tenantNonce、httpBody计算signature public static String calSignature(String token, String tenant_id, String tenantTs, String tenantNonce, byte[] httpBody) { try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); // 按照token、httpBody、tenant_id、ts、nonce的顺序拼接 // 本身为字符串的字段,需要使用utf-8方式编码成字节数组 // httpBody本身为bytes类型,因此无需编码 digest.update(token.getBytes(StandardCharsets.UTF_8)); digest.update(httpBody); digest.update(tenant_id.getBytes(StandardCharsets.UTF_8)); digest.update(tenantTs.getBytes(StandardCharsets.UTF_8)); digest.update(tenantNonce.getBytes(StandardCharsets.UTF_8)); // 将得到sha256使用16进制字符串表示 return bytes2Hex(digest.digest()); } catch (NoSuchAlgorithmException ignored) { return ""; } } public static String bytes2Hex(byte[] bts) { StringBuilder des = new StringBuilder(); String hex; for (byte bt : bts) { // 剔除负数强转成int后补上的"ffffff" hex = (Integer.toHexString(bt & 0xff)); // 始终用两个16进制代表一个byte,不够的在前面补“0” if (hex.length() == 1) { des.append("0"); } des.append(hex); } return des.toString(); } private static Headers.Builder createHeader(String tenantTs, String nonce, String signature) { Headers.Builder builder = new Headers.Builder(); builder.add("Tenant-Id", tenantId); builder.add("Tenant-Ts", tenantTs); builder.add("Tenant-Nonce", nonce); builder.add("Tenant-Signature", signature); builder.add("Request-Id", String.valueOf(UUID.randomUUID())); builder.add("Content-Type", "application/json"); return builder; } }