Fork me on GitHub

HTTP API

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.

Basic overview

The API consists of endpoints for the following:

  • registered backend endpoints discovery
  • registered backend endpoints invocation
  • cache invalidation

Discovery

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.

Invocation

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.

AggregateRequest

The POST body should be an AggregateRequest, which has a list of PartRequests. Each PartRequest corresponds to a single invocation of a registered endpoint and contains all the necessary parameters required.

AggregateResponse

The response from this endpoint will be an AggregateResponse, which has a list of PartResponses, each one corresponding to the response that each invoked registered endpoint has sent in response to a PartRequest.

Ways to use an AggregateResponse include:

  • Ignoring it (maybe you don’t care about the response)
  • Map/filter over the list of PartResponses to get information

A note about IDs

For 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")

Code samples

Scala client example

// 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)

Java client example

// 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.

Code samples

Scala client examples

// Flush user 123's profile data from the cache.
// Returns true if everything went OK.
val fResult: Future[Boolean] = octoClient.invalidateCacheFor("UserProfile", "uid", "123")

Java client examples

// Flush user 123's profile data from the cache.
// Returns true if everything went OK.
Future<Boolean> result = apiBuilder.invalidateCacheFor("UserProfile", "uid", "123");

API clients

While you’re free to use the HTTP API directly, we also provide a couple of API clients.

Java client

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>
Note
We cross-build the Java client against both Scala 2.10 and 2.11, in case you already have a scala-library.jar on your classpath. Change the artifactId to octoparts-java-client_2.10 if you prefer.

Scala WS client

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