State Management Within an Object

When getting or setting a variable involves coordination within a distributed system, it can be a good idea to manage the state of that variable with an object-oriented data structure, like a class or struct. The client code should be able to get or set the value of that variable without further responsibility to manage its state; a get or set either succeeds or fails.

In this example, a REST API access token is managed entirely by a TokenManager data structure, which provides a getToken method that returns either the empty string or a valid token string, with the idea that the client will provide the token as a header in its subsequent requests.

    TokenManager:
        token = ""

        getToken:
            if token == "" or isActive() == false
                token = authenticate()
            return token

        isActive:
            url = "http://example.com/simpleGet"
            response = httpGET(url, token)

            if response.success == true
                return true
            return false

        authenticate:
            url = "http://example.com/authenticate"
            jsonPayload = {
                "grantType": "password",
                "username": "myUsername",
                "password": "myPassword"
            }
            response = httpPOST(url, jsonPayload)

            if response.success == true
                return response.body.data
            return ""
                

TokenManager has three methods, of which isActive and authenticate are intended to be used only internally. isActive checks if the current value of the managed token is an active access token by providing it (presumably as a header) in a GET request to an endpoint of the least available complexity (resource needs, response size, etc.). If the request is successful, then the current value of token is active; otherwise it isn't.

When token shows to be inactive, it must be reassigned a new and active token. authenticate follows the authentication flow of the API, in this case password authentication, in order to retrieve an access token. It returns either the empty string or a token string, which becomes the current state of token.

The only responsibility of the client is to understand that an empty string getToken return value implies a failure to authenticate, and a non-empty string represents a valid token. The client can only proceed to make successful requests if it receives a non-empty token from getToken.

There's a few benefits to this approach. Maybe the most obvious is that the client code is not expected to have really any knowledge of authentication. The client also doesn't make any explicit requests; it can forget about HTTP and just get a string. Another benefit is token reuse; unless the program terminates, the same token is used until it's no longer active. Finally, it's simply easy to call a single method and receive an active access token.