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.