Calling Web Service in Elm
This time we will call the LanguageTool proofreading service to check the entered text.
We will look at commands, HTTP requests, and working with JSON in Elm. Feel free to look into the elm guide for an overview of these features.
The source code for this post is available in the 05-calling-proofread-service
folder in the elm-proofreading repository.
Changing from beginnerProgram
to program
Before we can make HTTP requests, there is one thing we need to do. That is, update our main
, which is a description of our application, from Html.beginnerProgram
to Html.program
.
Here are our old and new main
configurations:
Let’s look at new parts.
New update
function
In Elm we don’t perform HTTP requests, or any other action with side effects, directly in our code. Instead, we pass the Elm framework a Command that describes what action should be performed and what message should come back into our application once it’s done.
So we need a way to pass commands to Elm. Right now, our update
function takes a message and a model, and returns Elm a new model. Thus its signature is the following:
When we switch main
to be Html.program
, the update
function it requires would be:
The input parameters would stay the same—a message and the model, but the output would become a tuple. This tuple contains a new model, and a command we would like Elm to perform for us.
This new version of the update
function will allow us to perform HTTP requests.
init
and subscriptions
functions
There are two new functions that we need to specify for our new main
program:
init
function returns an initial state of the application.subscriptions
function returns a description of subscriptions needed by an app. We won’t use subscriptions for our application.
Now with an updated main
description, we can start implementing proofreading.
Adding Proofread Button
I will add a button to a page, that will initiate proofreading. Here’s the updated code for the view
function:
Using onClick
attribute I specify, that clicking on the button
will trigger the Proofread
message. I added this message to the Msg
type along with the case branch in the update
function:
In case of SetText
message, we change our model with new text and return Cmd.none
to signal Elm that there are no commands to run.
In case of Proofread
message, we return the same model, but there is a command that we want to perform. It is returned by our requestProofread
function.
LanguageTool Web Service
LanguageTool API provides a check
operation that checks the text for style and grammar issues. It requires two parameters:
text
—a text to check, we will pass entered text here.language
—language of passed text, this will be"en-US"
in our case.
To get a proofread result we need to POST a request to https://languagetool.org/api/v2/check with specified parameters.
The response will contain among other information a list of messages, that describe possible issues. For simplicity sake, we will get only a part of information. For each message we will get:
message
—description of an issue;offset
—starting index of the problematic word or phrase;length
—length of the problematic word or phrase.
Having this information would be enough to highlight problematic places in text and provide some additional context on an issue.
Here is an example of a JSON structure we expect to get from the service. All the other data from the response will be skipped:
Making HTTP Request
I’ve mentioned already that we are not going to call proofreading web service directly.
We need to create a Command that will contain the details of a call that should be performed, and a message that should be called afterward. We will pass this Command to Elm to perform, and Elm will pass us the result of a call with a message in the update
function.
Updating model
Before making a request, we need to update our data model. I’ll add a Comment
alias for a record that describes comments from the proofread service and update the model to store a list of such comments.
Updating Msg messages
Now, let’s add a ProofreadResult
message that should happen when Elm will perform our request. It will contain the Result
type with either a request error or a list of comments.
Creating Http request
Here is the code for creating our request to the service. I’ll show it all, and after that we’ll take a look at details:
To create a command in the requestProofread
function we’re calling Http.send
function that gets a request and a message ProofreadResult
to call afterward.
The request is created with the Http.post
function. It takes the following parameters:
url
—a service method URL;body
—a header and required parameters for a service call—text
andlanguage
;messageListDecoder
—a description for Elm on how to convert the JSON from the response into Elm objects. In our casemessageListDecoder
describes how to get a list ofMessage
records from JSON.
Processing request result
The created command is passed to Elm in the update
function. Elm performs the command and calls a web service. After that, Elm calls our update
function with ProofreadResult
message that contains the result of a request:
If the request succeeded, ProofreadResult
will contain a list of messages. In this case, we update our model with this list.
If something went wrong, we’ll get an error description. In this case, we just return the same model.
In the view
function, I’ve added the viewCommentsCount
function that will render a number of comments we received.
In the next post, we’ll show the proofreading results in a more friendly way.