public class RestStateRelay

  1. Object
  2. RestStateRelay

ImplementsStateRelay

A StateRelay over your own HTTPS endpoint, which is all most applications need.

Continuity.setRelay(new RestStateRelay("https://api.example.com/continuity") {
    protected String getToken() {
        return session.getAccessToken();
    }
 });

The contract

Two requests against the one URL you supply:

  • POST with the state as a JSON body and Content-Type: application/json. Store it against the signed-in user, replacing whatever you held for them. Any 2xx means stored.
  • GET, answering with the newest state you hold for that user as the same JSON, or an empty body when you hold none. A 404 also means none.

The JSON is exactly what StateCodec.toJson(AppState) produces, and it is a closed shape: your endpoint stores and returns the document, and never needs to look inside it.

Identity is yours

Which states belong to the same person is the one question the framework cannot answer, which is why the token comes from getToken() rather than from a constructor: it is read at each request, so a session that refreshes its token is followed automatically. Return null for an endpoint that identifies the user some other way – a cookie, mutual TLS – and the header is simply omitted.

Threading

Both methods are called from a background thread and block, which is what the framework expects of a relay. getToken() is called on that same thread, so it must not wait on the event dispatch thread.

Constructors

public RestStateRelay(String url)Creates a relay against an HTTPS endpoint.

Methods

public String getUrl()The endpoint this relay talks to.
protected String getToken()The bearer token to present, read once per request.
public void publish(AppState state) throws IOExceptionSends a state.
public AppState fetch() throws IOExceptionAsks for the newest state this user has on any device.

Inherited methods

Constructor details

RestStateRelay

public RestStateRelay(String url)
Creates a relay against an HTTPS endpoint.

Parameters

url String
the endpoint, which must be HTTPS

Throws

IllegalArgumentException
when the URL is null, empty or not HTTPS

Method details

getUrl

public String getUrl()
The endpoint this relay talks to.

Returns

the URL

getToken

protected String getToken()

The bearer token to present, read once per request. The default returns null, which sends no Authorization header.

Changing accounts

Install a NEW relay for the new account – Continuity.setRelay(StateRelay) – rather than returning a different account’s token from the same object. A publish that was authorised for the previous account can still be between the framework’s last check and this read when the switch happens, and the framework cannot bind a token it is not allowed to read. What it can recognise is an object that is no longer installed, which it then refuses; an object that quietly starts answering for someone else looks identical to one that refreshed its own session.

Returns

the token, or null for none

publish

public void publish(AppState state) throws IOException
Sends a state. Called after each checkpoint, so implementations that talk to a slow endpoint should coalesce rather than send every one.

Parameters

state AppState
the state to send

Throws

java.io.IOException
when the send failed. The framework logs it and keeps the state, which the next checkpoint’s publisher sends – unless a newer state has superseded it by then, or the user signed out in between. It is not retried on a timer: one attempt per change beats spinning against an endpoint that is down.

fetch

public AppState fetch() throws IOException
Asks for the newest state this user has on any device. Returning this device’s own most recent state is fine and expected – the framework recognizes its own echo by device id and sequence, and ignores it.

Returns

the state, or null when the endpoint has nothing

Throws

java.io.IOException
when the fetch failed