One of the features of ApiSnapshot is support for Basic Authentication.
While we were rebuilding the whole application in Elm,
we had to port the “Add Basic Authentication” feature.
This feature can be accessed from the “More” drop-down on the right-hand side of the app
and it lets user add username and password to the request.
Let’s see how the Model of our Elm app looks.
Here is the Model in Request.MainRequest module.
username and password fields are optional for the users
so we kept them as Maybe types.
Note that API always responds with username and password whether
user clicked to add Basic Authentication or not.
The API would respond with a null for both username and password
when a user tries to retrieve a snapshot for which
user did not fill username and password.
Here is a sample API response.
Let’s look at the view code which renders the data received from the API.
To get the desired view we apply following rules.
Check if both the values are string.
Check if either of the values is string.
Assume that both the values are null.
This works but we can do a better job of modelling it.
What’s happening here is that
we were trying to translate our API responses directly to the Model .
Let’s try to club username and password together into a new type called BasicAuthentication.
In the model add a parameter called basicAuthentication which would be of type Maybe BasicAuthentication.
This way if user has opted to use basic authentication fields
then it is a Just BasicAuthentication and we can show the input boxes.
Otherwise it is Nothing and we show nothing!
Here is what the updated Model for Request.MainRequest would look like.
Elm compiler is complaining that we need to make
changes to JSON decocding for APISnapshotRequest type
because of this change.
Before we fix that
let’s take a look at how JSON decoding is currently being done.
Now we need to derive the state of the application
from our API response .
Let’s introduce a type called ReceivedAPISnapshotRequest
which would be the shape of our old APISnapshotRequest with no basicAuthentication field.
And let’s update our requestDecoder function to return a Decoder of type ReceivedAPISnapshotRequest
instead of APISnapshotRequest.
We need to now move our earlier logic that checks to see
if a user has opted to use the basic authentication fields or not
from the view function to the decodeAPISnapshotRequest function.
We extract the username and password into extractedCreds as a Pair
from ReceivedAPISnapshotRequest after decoding and construct our APISnapshotRequest from it.
And now we have a clean view function
which just takes a BasicAuthentication type
and returns us a Html Msg type.
We now have a Model that better captures the business logic.
And should we change the logic of basic authentication parameter selection in the future,
We do not have to worry about updating the logic in the view .