Skip to content

Instantly share code, notes, and snippets.

@tsnow
Created November 11, 2013 20:16
Show Gist options
  • Save tsnow/7419623 to your computer and use it in GitHub Desktop.
Save tsnow/7419623 to your computer and use it in GitHub Desktop.
Temporary Subscription / WebHook API
// To get all the events for a given device during a particular
// period without polling, one can create a subscription API.
// This is somewhat similar to PubSub, save that each event is
// it's own http connection.
//
// This is an extension of a simple firehose API,
// which allows subscribing to specific subfeeds. Here we'll assume that
// the subfeeds are subscribed to by device_name/id, but any static list
// of characteristics would do.
//
// yourserver.com Client => gpshost.com POST /subscriptions{?device_name/id,sink_url}
// Response:
{
"result": {
"status" : "success"
}
}
// As each event enters the gpshost.com service,
// they must be multiplexed to all subscribers.
//
// yourserver.com POST {sink_url} <= gpshost.com Event Feed Client
// Request:
{
"events": [
{
"type" : "position",
"latitude": "33.11",
"longitude" : "33.10"
}
]
}
// Or Request:
{
"events": [
{
"type" : "on",
"os": "Mac OS X",
"nsa_wiretap" : "true"
}
]
}
// sink Response:
{
"result": {
"status" : "success"
}
}
// When yourserver.com no longer cares about the event feed, it unsubscribes.
// yourserver.com Client => gpshost.com POST /subscriptions/unsubscribe{?device_name/id,sink_url}
// Response:
{
"result": {
"status" : "success"
}
}

Coupling Concerns

  • Responses: Both sides must understand and properly format response json documents. There's no incentive for these documents to be similar.
  • Call flow state machine: yourserver.com must understand all possible state transitions (including epsilion transitions like timeouts) and error cases for the subscription and unsubscription endpoints.
  • Event state machine: yourserver.com must understand all possible state transitions (including epsilion transitions like timeouts) and error cases for the relationships between individual events.
  • Subscription/Unsubscription request forms:
    1. yourserver.com must understand the subscription creation and unsubscription response data structures, including the names and values of all relevant components.
    2. yourserver.com must know the subscription creation / unsubscription URLs
    3. yourserver.com must understand the names and values of the subscription creation / unsubscription URL parameters
  • event feed request forms:
    1. yourserver.com must understand the names and values of the event feed callback request parameters
    2. yourserver.com must understand and differentiate between different types of events
  • both sides must agree regarding the name and value of the device_name/id, or subfeed identifying parameters.
  • both sides must agree on the method, occurrances, and content of authentication.

Decoupled Components

  • gpshost.com need not understand any yourserver.com logic or state, save for:
    1. the subscription sink_url parameter will contain an endpoint which understands the event feed callback request parameters
    2. the sink_url will respond with json, specifically that which can be understood by the event feed client at gpshost.com.

Effect of Libraries

https://github.com/ridecharge/pim_meter_events

RIPS ships a client library to ease subscribing to its PIM event streams. This allows client developers to set up global state and handle global error conditions which are consistent across requests, and an indirection layer to hide the url structure and request formats of the endpoints of the API. The library provides an indirection layer on top of the subscription / unsubscription reponse structure as well as understanding the global error format. The pim_meter_events library provides strong support for generating appropriate callback endpoints. Specifically, middleware is provided which accepts and parses event feed requests. A reactor pattern listener is provided which allows listening to only a subset of the events returned in the feed.

Evolvability Constraints

The pim_meter_event API can evolve independently of clients by adding new endpoints, and by adding additional response data, or adding optional parameters to existing endpoints. Individual calls are locked in their required request parameters. Any change to existing URLs, authentication, device_names/ids, or increase in the required parameter set for any call will require a whole API/Client library bump, including changes to all clients.

With the addition of the client library: By requiring all clients to use their libraries they allow additional independent evolution by adding new events, and adding new fields to existing events. By shipping a new version of their API client library, and deprecating older library versions, they can transparently transfer new and existing (upgraded) clients to different URLs and URL structures, as long as the baseline functionality is unchanged. They can even implement new request flows and authentication methods, as long as the new flows are congruent to the existing functionality; i.e. as long as the input parameters to the library methods and responses from the library methods do not change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment