The REST API of Octoparts is relatively small. Those already familiar with Swagger can simply head to the built-in Swagger documentation, which is hosted at octoparts.herokuapp.com/swagger-ui.
The API consists of endpoints for the following:
The discovery endpoint is used for programmatically discovering the backend endpoints that have been registered in a given Octoparts deployment. The response is a list of registered endpoints, with each item showing what URL will be hit with, what parameters are registered to it, what HTTP method will be used when it is invoked, as well as cache-related settings.
This is likely going to be your most-often used Octoparts endpoint. It is the endpoint that you will do a POST to in order to invoke your registered endpoints.
The POST body should be an AggregateRequest
, which has a list of PartRequest
s. Each PartRequest
corresponds to a single invocation of a registered endpoint and contains all the necessary parameters required.
The response from this endpoint will be an AggregateResponse
, which has a list of PartResponse
s, each one corresponding to the response that each invoked registered endpoint has sent in response to a PartRequest
.
Ways to use an AggregateResponse
include:
PartResponse
s to get informationFor every PartRequest
, you must supply the partId
. This is the ID that is registered in the admin UI, e.g. UserProfile
, and tells Octoparts which endpoint it should invoke.
Also, you can optionally specify an id
for the PartRequest
. This is a unique ID for that request, as opposed to the ID of the endpoint that it’s calling, which is useful if you want to invoke the same endpoint multiple times in the same aggregate request.
For example, say that you want to display a message sent from user 123 to user 456, so you want both users’ profile information. In this case you would send two part requests that would look something like this (in Scala):
Seq(
PartRequest(partId = "UserProfile",
id = Some("profile_123"),
params = Seq(PartRequestParam("uid", "123"))),
PartRequest(partId = "UserProfile",
id = Some("profile_456"),
params = Seq(PartRequestParam("uid", "456")))
)
If you don’t specify an id
for a PartRequest
, it will automatically be set to be the same as the partId
.
When the AggregateResponse
comes back and you want to extract a particular PartResponse
, you can look it up using the id
you specified on the PartRequest
:
val user123profile = aggResp.findPart("profile_123")
// Build an AggregateRequest to send to Octoparts
val aggregateRequest = AggregateRequest(
requestMeta = RequestMeta(
// Most of these fields are optional
id = UUID.randomUUID().toString,
serviceId = Some("frontend"),
userId = Some("123"),
requestUrl = Some("http://www.m3.com/foo"),
timeoutMs = Some(500L)
),
requests = Seq(
// A list of the endpoints you want to call, with parameters to send
PartRequest(partId = "UserProfile", params = Seq(PartRequestParam("uid", "123"))),
PartRequest(partId = "LatestNews", params = Seq(PartRequestParam("limit", "10")))
)
)
// Send the request, get back a Future
val fResp: Future[AggregateResponse] = octoClient.invoke(aggregateRequest)
// Build an AggregateRequest to Send to Octoparts.
// Arguments (all optional and therefore nullable):
// user ID, session ID, user agent, requested URL, timeout (ms)
RequestBuilder request = apiBuilder.newRequest(
"123", "mySessionId", "myUserAgent", "http://www.m3.com/foo", 500L);
request.newPart("UserProfile", null).addParam("uid", "123").build();
request.newPart("LatestNews", null).addParam("limit", "10").addParam("foo", "bar").build();
// Send the request, get back a Future
Future<ResponseWrapper> future = apiBuilder.submit(request.build());
// For convenience, block on the future if you want to
ResponseWrapper responseWrapper = FutureResponseHandler.awaitResponse(future, 1000L);
// Note: The Java client doesn't include any helpers for JSON deserialization
String userProfileJson = responseWrapper.getPartResponse("UserProfile").getContents("");
String latestNewsJson = responseWrapper.getPartResponse("part2").getContents("[]");
The cache invalidation endpoints allow you to invalidate the cached responses stored in Octoparts. They allow you to invalidate caches by backend endpoint name, endpoint name with parameter name-value pair, cache group name, and cache group name with parameter value.
For information on what this means in detail, see the Caching page.
// Flush user 123's profile data from the cache.
// Returns true if everything went OK.
val fResult: Future[Boolean] = octoClient.invalidateCacheFor("UserProfile", "uid", "123")
// Flush user 123's profile data from the cache.
// Returns true if everything went OK.
Future<Boolean> result = apiBuilder.invalidateCacheFor("UserProfile", "uid", "123");
While you’re free to use the HTTP API directly, we also provide a couple of API clients.
This client is actually implemented mostly in Scala, but it provides seamless Java interop. It’s based on the Ning AsyncHttpClient.
See here for an example of how to use it in your application.
Maven:
<dependency>
<groupId>com.m3</groupId>
<artifactId>octoparts-java-client_2.11</artifactId>
<version>2.4.1</version>
</dependency>
scala-library.jar
on your classpath. Change the artifactId to octoparts-java-client_2.10
if you prefer.
This is a Scala client, designed to be used within a Play application. It uses the Play WS library for its HTTP calls.
See here for an example of how to use it in your application.
SBT:
libraryDependencies ++= Seq(
"com.m3" %% "octoparts-scala-ws-client" % "2.4.1"
)
Just like the Java client, we cross-publish for Scala 2.10 and 2.11.
Next: Read about Caching