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.