Tutorial: Consuming REST APIs
In this tutorial I’ll show you everything you need to know about consuming REST APIs with Linx.
I will show you how to make a number of different types of requests and some tips and tricks on how to handle various types of responses.
- Sending a request
- Handing a response
- Dynamic request URLs
- Sending a URL parametrized request
- Adding query values
- Handling varying responses
- List responses
- Sending content
- Re-using data objects
You can download a copy of the sample Linx Solution used in this Tutorial below.
Linx 5: Solution.lsoz (18.5 KB)
Linx 6: RESTSolution.zip (20.4 KB)
Feel free to contact support@linx.software and we'll assist.
Sending a basic request
A GET
request is going to be made which makes a request to this endpoint : http://api.icndb.com/jokes/random
The response will contain a JSON object in the form of a string which contains joke related information.
- Create a new Solution.
- Rename the default function to
GetRandomJoke
. - Add the REST plugin to your solution
- Drag a CallRESTEndpointFNC into GetRandomJoke .
- Set the URL to the below:
http://api.icndb.com/jokes/random
- Right-click on the CallRESTEndpointFNC in GetRandomJoke and click Enable Logging.
- Select the GetRandomJoke function in the Solution Explorer and start the Debugger.
- When the GetRandomJoke function executes, you should see the request being made and the subsequent response being returned in the Debug Output panel like below:
CallRESTEndpoint: URL Constructed http://api.icndb.com/jokes/random
CallRESTEndpoint: HTTP client created
CallRESTEndpoint: Sending GET request
CallRESTEndpoint: Request Headers: None
CallRESTEndpoint: Response received
CallRESTEndpoint: -----------------
CallRESTEndpoint: Response code: 200 (OK)
CallRESTEndpoint: Response Body:
CallRESTEndpoint: { "type": "success", "value": { "id": 141, "joke": "The original draft of The Lord of the Rings featured Chuck Norris instead of Frodo Baggins. It was only 5 pages long, as Chuck roundhouse-kicked Sauron's ass halfway through the first chapter.", "categories": [] } }
CallRESTEndpoint: -----------------
CallRESTEndpoint: Response Headers:
CallRESTEndpoint: Transfer-Encoding = chunked
CallRESTEndpoint: Connection = keep-alive
CallRESTEndpoint: access-control-allow-origin = *
CallRESTEndpoint: access-control-allow-methods = GET
CallRESTEndpoint: vary = User-Agent
CallRESTEndpoint: CF-Cache-Status = DYNAMIC
CallRESTEndpoint: cf-request-id = 0677ef244c0000070ae7b33000000001
CallRESTEndpoint: Report-To = {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report?s=WyMy3iOfmuxMb4lUn%2FswmxyOBKEVyX%2B5EYSg9j9YxcoR4SuShpxBPjs6kxMRhATZXXJ4Wu2j3XLe%2Fk5mUJJmpbrSpF8TohMg%2F%2B6RbYlu"}],"group":"cf-nel","max_age":604800}
CallRESTEndpoint: NEL = {"report_to":"cf-nel","max_age":604800}
CallRESTEndpoint: CF-RAY = 5f39b4807d5e070a-LHR
CallRESTEndpoint: Cache-Control = must-revalidate, no-cache
CallRESTEndpoint: Date = Tue, 17 Nov 2020 13:12:44 GMT
CallRESTEndpoint: Set-Cookie = __cfduid=dfba9c643a6d6f89c89e89de426e00aa31605618764; expires=Thu, 17-Dec-20 13:12:44 GMT; path=/; domain=.icndb.com; HttpOnly; SameSite=Lax
CallRESTEndpoint: Server = cloudflare
CallRESTEndpoint: Content-Type = application/json
CallRESTEndpoint: Expires = Sat, 26 Jul 1997 05:00:00 GMT
CallRESTEndpoint: Content-Length = 267
Process end reached.
The Definition tab (next to the Properties tab in the Linx Designer) shows the output of selected elements. Click on the CallRESTEndpointFNC to see there that it has the following output values:
- ResponseHeaders: Header list in the format
key:value
pairs which contain metadata associated with the response. - ResponseBody: The
Response Body
of the object. This will deserialized into the structure set as the Output type. - StatusCode: The HTTP Status Code of the request i.e.
200
,404
.
Working with the response body
By default, the CallRESTEndpointFNC has its Output type set to a StringTYP . This means that no deserialization is performed on the data and it is returned in the ResponseBody
as a single string, as you can see in the Debug Values panel on the right in the above graphic.
{ "type": "success", "value": { "id": 141, "joke": "The original draft of The Lord of the Rings featured Chuck Norris instead of Frodo Baggins. It was only 5 pages long, as Chuck roundhouse-kicked Sauron's ass halfway through the first chapter.", "categories": [] } }
Even though the above is a JSON string, Linx is configured by default to interpret this as a single StringTYP .
In order to work with the data as individual objects, you are able to assign the output as a complex object.
Create a Type object
To do this you need to create a TYP which will map the fields from the response onto data objects within Linx.
You are able to import the initial ResponseBody
string that is returned from the CallRESTEndpointFNC.
To do this:
- Repeat the steps in the section above and debug the GetRandomJoke function.
- Copy
Response Body
string from the Debug Output. - Right-click on a Project in the Solution Explorer.
- Click Import Type.
- Paste the copied text into the editor and change the Name to
JokeResponse
. - Click Create.
This will create a JokeResponseTYP in the Solution Explorer. This object can then be referenced as a structure throughout the Solution.
Reference the Type object as the output structure
Now that you have created the JokeResponseTYP which maps to the Response Body
, you are able to map the response of the CallRESTEndpointFNC to this object.
To do this:
- In the Output type field , select your new JokeResponseTYP under Project > JokeResponse
- Debug the GetRandomJoke function.
- Take a look at the Debug Values panel and notice how the JSON string has now been deserialized into the JokeResponseTYP.
In subsequent functions in your function, you will now have access to the individual fields contained in the Response Body
.
Returning the data from the function
To make the GetRandomJoke function re-usable, we are now going to configure the GetRandomJoke function to have a single $.Result which will be a StringTYP and will return the value of CallRESTEndpoint.ResponseBody.value.joke
.
When the GetRandomJoke function is called from another function or event, a single string containing the joke
will be returned.
To configure the $.Result:
- Select the GetRandomJoke function in the Solution Explorer
- Expand the Result editor.
- Add an $.Result and select the Type as
String
. - Add a SetValueFNC onto the GetRandomJoke function
- Set the Target as
$.Result
. - For the Source, reference
CallRESTEndpoint.ResponseBody.value.joke
.
To test out the re-usability of the GetRandomJoke function, create a new function in the Solution Explorer.
Drag the GetRandomJoke function from the Solution Explorer into this new function.
Debug the new function with a Breakpoint added to the GetRandomJoke function.
Step into the GetRandomJoke function and take note of how the values are assigned to the Result. When you return to the main function, you will see the joke
being returned from the GetRandomJoke function call.
Dynamic URLs
In the below example, a specific joke
resources is retrieved by including the id
of the joke in the request URL:
http://api.icndb.com/jokes/{id}
It will return a specific joke
in the same format of the GetRandomJoke.
In this case both the endpoints http://api.icndb.com/jokes/random
and http://api.icndb.com/jokes/{id}
share the Base URL http://api.icndb.com/jokes
as well as returning the same single joke
JSON structure.
We are able to copy the GetRandomJoke function out and tweak it slightly to account for the slight difference.
Before we do that, we are going to make our Base URL a $.Setting so that we can reference it throughout the Solution. This allows you to alter the Base URL in a single place and it will have Solution wide effects, this can be things such as changing environments, version changes or plain URL changes. After this, for each request we can just add the suffix of the specific path i.e. /random
or /{id}
.
It is advised that you use expressions based on $.Settings to build up URLs in cases where API versions and resource location may change.
To create a Base URL to reference:
- Open up the $.Settings in the top menu.
- Add a new setting with the Name of
chuckNorrisBaseUrl
- As the Value, set it as
http://api.icndb.com/jokes
. - Go back to the GetRandomJoke function and into the CallRESTEndpoint Properties.
- In the URL, open the expression editor (EX).
- Add the following expression:
= $.Settings.chuckNorrisBaseUrl + "/random"
- Debug the GetRandomJoke function, notice how the URL will be built up at runtime.
Fetching a specific resource
Often when working with REST APIs, specific resources are retrieved by indicating the specific resource with a parametrized URL request. This involves building up dynamic URLs which will contain identifiers for certain resources.
In this part of the tutorial, we are going to be making a request for a specific joke using an id
as a parameter in the URL.
A GET
request will be made to the endpoint http://api.icndb.com/jokes/{id}
.
It was mentioned earlier how the first request we made and the one we are going to make share a similar URL as well as the same response structure.
Because of these similarities we can copy the whole of the GetRandomJoke function and create a new one from it. We can then alter the function to account for the variations of the request.
To achieve this:
-
Right-click on the GetRandomJoke function in the Solution Explorer.
-
Click Copy.
-
Right-click on the Project folder in the Solution Explorer.
-
Click Paste.
-
Rename the GetRandomJoke2 function to
GetSpecificJoke
. -
Add an $.Parameters field to the GetSpecificJoke function with the Name of
id
-
Alter the request URL to use the
$.Input.id
with the below expression:= $.Settings.chuckNorrisBaseUrl + "/" + $.Parameters.id
-
Debug the function, you will notice there is an available input field in the Debug Values panel. This allows you to simulate the function being called. Try the function out with several numbers [1-5].
At runtime the URL will be built from the base URL as a $.Setting, and the
id
passed in to the GetSpecificJoke function.URL Constructed http://api.icndb.com/jokes/5
As both of the requests return the same type of object, there is no need to do any further mapping.
Now to test out the re-usability of the GetSpecificJoke function, we are going to create a new function GetSeveralSpecificJokes which will call the GetSpecificJoke function and pass in different id
values contained in a list. We are then going to add the joke
returned from each call to the GetSpecificJoke function to a list containing the jokes of all the joke ids in the list.
To achieve the above:
-
Create a new function in the Solution Explorer.
-
Rename it to
GetSeveralSpecificJokes
. -
Add a ListTYP to the function and rename it to
ListOfJokeIDs
. This will create an empty instance of a list[]
-
Expand the ListOfJokeIDs item editor and add several items containing the items:
[1,2,3,4,5]
-
Add another ListTYP to the function and rename it to
ListOfJokes
[]
. -
Add a ForEachFNC below the ListOfJokeIDs and rename it to
ForEach_JokeID
. -
Set the List of ForEach_JokeID as
ListOfJokeIDs
. -
Drag the GetSpecificJoke function from the Solution Explorer, onto the GetSeveralSpecificJokes function, inside the execution path of the ForEach_JokeID. This means that for each item in the ListOfJokeIDs, the GetSpecificJoke function will execute and return a single
joke
. -
An
id
field will appear in the properties of the GetSpecificJoke function call on the canvas. This is because the GetSpecificJoke function takes in an$.Parameters.id
. -
Each time the GetSpecificJoke function is called, we are going to pass in the current value of the ForEach_JokeID which will be a number from 1 - 5.
To do this, reference
ForEach_JokeID.Loop
as theid
parameter of the GetSpecificJoke function call. -
After the the GetSpecificJoke function is called, it will return a string containing a joke. We are going to add this returned value to the ListOfJokes.
This is done by adding an AddToListFNC below the GetSpecificJoke function call but still within the execution path of the ForEach_JokeID.
-
Set the List of the AddToList as
ListOfJokes
. -
Set the Value of the AddToList as
GetSpecificJoke.joke
. -
Debug the GetSeveralSpecificJokes function with breakpoints so that you can see the flow of data.
The result will be ListOfJokes containing strings like below:
[
"Chuck Norris uses ......ets the pleasure.",
"MacGyver can build an ai....rris can kill him and take it.",
"Chuck Norris doesn't read books. He stares them down u... he wants.",
"If you ask Chuck Norris w....o seconds till". After yo..at?"..ks you in the face.",
"Chuck No.....re his dad did."
]
Using Query parameters
Typically, you need to supply additional parameters in the query string of the request URL when retrieving data in order to limit the results.
In the below example, an escape
parameter is included in the request.
http://api.icndb.com/jokes/random?escape=javascript
This indicates to the API that it must return the data but not include JavaScript characters in the response.
Another example can be found below:
http://api.icndb.com/jokes/random?limitTo=[nerdy,explicit]
In order to add the query string to your request, expand the Query string property and add the above field from the first example like below.
When a request is made, the query values will be URL encoded and appended onto the request URL.
You will notice how the response joke
does not contain any HTML characters.
Varying response formats
Occasionally, responses are returned and the exact type of object is not known until the response is returned, in cases like these Linx will not be able to implicitly deserialized the response body. Therefore you must implement custom logic like below to handle such requests.
To demonstrate:
-
Expand the ListOfJokeIDs item editor and add 2 additional
id
values like below:
[1,2,3,4,5,6,7]
-
Debug GetSeveralSpecificJokes
-
You will notice that an error is thrown like below:
Exception at GetSpecificJoke :
GetSeveralSpecificJokes.GetSpecificJoke: GetSpecificJoke.CallRESTEndpoint: Error converting value "No quote with id=7." to type 'CustomTypes_5a956d5dfa3f45a391e2e6f6497bf31f._4c5174890ed7419bb42546f15d9b7f3f'. Path 'value', line 1, position 64.
Could not cast or convert from System.String to CustomTypes_5a956d5dfa3f45a391e2e6f6497bf31f._4c5174890ed7419bb42546f15d9b7f3f.
GetSpecificJoke Trace Log:
URL Constructed http://api.icndb.com/jokes/7
HTTP client created
Sending GET request
Request Headers: None
Response received
-----------------
Response code: 200 (OK)
Response Body:
{ "type": "NoSuchQuoteException", "value": "No quote with id=7." }
If you look at the stack trace of the error, you will see that a successful request was made and a 200 (OK)
response code was returned. However, even though the response was successful, an error was thrown because the object returned in the Response Body
cannot correctly map to the configured Output type.
If you compare the returned Response Body
:
{
"type":"NoSuchQuoteException",
"value":"No quote with id=7."
}
With the JokeResponseTYP configured as the Output type:
{
"type":"string",
"value":{
"id":0,
"joke":"string",
"categories":[
"string1",
"string2"
]
}
}
The JokeResponseTYP contains two fields (type
,value
). The value
field contains a nested object containing fields for the id
, joke
and categories
field.
In the “error” response, the field value
is a StringTYP , and therefore cannot map to the TypeTYP object JokeResponse_valueTYP.
This often happens when working with APIs whereby the possible structure of the objects returned varies from response to response.
In order to handle such scenarios, you need to add additional logic to deserialized the Response Body
into the correct object.
We are now going to add logic which will return the Response Body
as a StringTYP , we will then add decision making logic to parse the response for the success
field for the text “NoSuchQuoteException”.
This is done by resetting the Result type to String
. This will then return any Response Body
as a StringTYP .
Using an IfElseFNC , the text returned from the request is searched for the text “NoSuchQuoteException”.
If the above text is detected, then the $.Result
is set to a default value, if not then the ResponseBody
is deserialized into the JokeResponseTYP $.Result
is set to the JokeResponse.value.joke
.
To demonstrate,
-
Go back to the GetSpecificJoke function from earlier.
-
Alter the Output type of the CallRESTEndpointFNC to be
String
. -
Add an IfElseFNC below the CallRESTEndpointFNC .
-
Add a condition to the IfElseFNC with the the name of
JokeExists
and with the value containing the below expression:= !CallRESTEndpoint.ResponseBody.Contains("NoSuchQuoteException")
At runtime the above expression will evaluate if the text returned from the response does not (!) contain the text “NoSuchQuoteException”.
-
We can assume if it the text doesn’t contain the text “NoSuchQuoteException”, then it will map correctly to the JokeResponseTYP.
With Linx, you are able to explicitly assign a StringTYP to a TypeTYP and it will deserialize the text into the object if it can.
In order to do this, drag the JokeResponseTYP from the Solution Explorer into the JokeExists execution path. This will create a local instance of the JokeResponseTYP which can be used to work with data in this structure locally.
-
For the Value, reference the
CallRESTEndpoint.ResponseBody
.Now you are able to access the individual fields of the
Response Body
by referencing the local instanceJokeResponse.#fieldname#
. -
You would have noticed a validation error appear for the
GetSpecificJoke.SetValue
. This is because theCallRESTEndpoint.ResponseBody.value.joke
value no longer exist as we set it to a string.You now need to alter the SetValue to reference the local instance of the JokeResponseTYP as the Source. In order to access the local JokeResponseTYP, you need to be within its scope, which is currently the JokeExists execution path.
Drag the SetValue from the bottom of the function, into the JokeExists execution path, below the the local instance of the JokeResponseTYP.
For the Source, update the reference to the below:
= JokeResponse.value.joke
- Now, select the Show else property to create an alternate execution flow.
- In the Else execution flow, add a SetValueFNC and give it the Name of
SetValue_NoJoke
. - For the Target reference the
$.Result
. - For the Source, we are going to return a default message with the ID of the joke.
This is done with the below expression:="No joke for ID :" + $.Parameters.id
If you debug the GetSeveralSpecificJokes function again, step into the GetSpecificJoke function per id
and take note of how the Response Body
is assigned to the TypeTYP structure.
When the id
of 7
is encountered, the response is handled and no explicit error is thrown.
Responses as Lists
Typically, responses contain richer information that just a basic type. Often, lists of objects are returned containing basic types as well as nested objects. This could be something like a list of orders
being retrieved, where each order
consists of an id, date, customer, total cost and a list of items
.
When you import a response which is a list of child objects, only the child object will be imported. This is to say, if you import a list of
orders
, Linx will create a single order
TypeTYP. Similar to setting a List<basic type>
, using the type editor, set the List<TYPE>
by referencing your imported type as List<your Type>
.
To create a list of these items to use as the output structure of the response, in the Result type property, for example set the Result type as List<order>
.
To demonstrate , a request is made to the CoinGecko Cryptocurrency market API.
In the below example, a GET
request is made to the URL:
https://api.coingecko.com/api/v3/coins/list
The response contains a list of coin
objects which contains a id
, symbol
and name
field containing the information related to the cryptocurrency coin/token like below:
[
{
"id": "01coin",
"symbol": "zoc",
"name": "01coin"
},
{
"id": "02-token",
"symbol": "o2t",
"name": "O2 Token"
},
{
"id": "0cash",
"symbol": "zch",
"name": "0cash"
}
]
In order to access these objects, the response body needs to be imported as a TypeTYP. The returned list then needed to be looped through.
To demonstrate, a new function is going to be created which makes a request to retrieve all the coin objects. These objects are then looped through at added to a list containing the name of each coin:
-
Create a new function and name it
GetAllCoins
-
Add a CallRESTEndpointFNC to the function.
-
Set the URL to
https://api.coingecko.com/api/v3/coins/list
. -
Import the
Response Body
and give it the name ofcoin
.You will notice that only a single TypeTYP is created and not a list. This object is now a type so it can be referenced liked any basic type with
List<Type>
. -
Set the Result type of the CallRESTEndpointFNC to
List
. -
Using the field editor set the
List<type>
toList<Project.coin>
. -
Debug the GetAllCoins function and notice how the response body is now deserialized into a a list containing
coins
objects.
In the Debug Values panel you are able to see all the items in the list.
In order to access individual objects in the list, you need to use a ForEachFNC and loop through the list of objects. In each loop you will then have access to that particular object.
To demonstrate, the list of coins returned in the response is going to be looped through. The name
of each coin
item will then be added to a list:
-
Add ForEachFNC to the GetAllCoins function and rename it
ForEach_coin
. -
Reference the
CallRESTEndpoint.ResponseBody
as the List to loop through. -
Add a ListTYP to the beginning of the GetAllCoins function and rename it
ListOfCoins
.This will store the
name
of eachcoin
object. -
Within the execution path of the Loop , add an AddToListFNC .
-
For the List , reference the
ListOfCoins
. -
For the Value , reference the current loop
name
field value i.e.ForEach_coin.Loop.name
-
Add $.Result type to the function GetAllCoins properties. Select the Type as
List<String>
-
Add a SetValueFNC and give it the Name of
SetValueResult
. -
For the Target reference the
$.Result
. -
For the Source reference the
ListOfCoins
. -
Debug the solution. Observe the ListOfCoins values in the debug output screen.
Nested list objects
Often, resources are returned in a list, and within each item in the list, there is another list.
That is to say there is a List present inside your Response Body
, whether its a List<string>
, List<object>
or List<List<>>
. You will need to first loop through the higher level list, and then for each item, you will have to loop through the nested list to access those nested objects and fields.
Take the example of the below Response Body
which contains a list of episode
objects. Within each episode
, there is a list of characters
.
[
{
"episode_id":100,
"title":"Coushatta",
"season":"4",
"air_date":"09-24-2018",
"characters":[
"Jimmy McGill",
"Mike Erhmantraut",
"Kim Wexler",
"Howard Hamlin",
"Chuck McGill",
"Nacho Varga"
]
}
]
In order to access the nested list i.e. characters
, a loop needs to be performed on the list of episode
, and then for each episode
, an additional iteration must be performed on the characters
list of that particular episode
.
To demonstrate the approach, an example request is made to the Breaking Bad API.
In the below example, a GET
request is made to the https://www.breakingbadapi.com/api/episodes
endpoint.
This will return a list of episode
objects like in the sample above. Within each episode
, there is a List<string>
containing the names of the characters present in that attitude.
The names of all the characters will be added to a ListTYP one by one.
To challenge yourself:
-
Create a new function and name it
GetAllBreakingBadCharacters
-
Add a ListTYP and rename it to
CharacterList
. -
Add a CallRESTEndpointFNC to the function.
-
Set the URL to
https://www.breakingbadapi.com/api/episodes
. -
Copy the
Response Body
and Create or Import a newType
with the name ofepisode
-
Set the Result type to
List<Project.episode>
. -
Add a ForEachFNC. Name it
ForEach_episode
and loop through theResponse Body
returned from the request. -
Under for each
episode
, add another ForEachFNC and loop through thecharacters
list of that iteration. Name it asForEach_characters
. Set the List to=ForEach_episode.Loop.characters
. -
Add AddToListFNC under
ForEach_characters
. Set the List toCharacterList
and source as=ForEach_characters.Loop
. -
Add a SetValue under
ForEach_characters
. Rename it toSetValueResult
. Set Target as$.Result
and Source asCharacterList
Sending content
So far, we’ve only dealt with how to make varying requests (GET
) and receive the varying responses. What we haven’t touched on is sending content such is the case with POST
, PUT
and PATCH
.
The below section describes how to send an `application/json` request body with a request.
Typically, request bodies require data to be submitted in some structured form, most often this is JSON
. Examples of these are typically provided on the target APIs reference documentation.
In order to send a JSON
(or XML
) request body, you must configure the correct Body format respectively.
For the Body, you need to reference a data object which will be serialized appropriately.
In order to send the correct data structure, you must create a TypeTYP which maps to the same fields and types of the expected request body structure.
Just like when working with response bodies, you are able to import the sample request body from the documentation site into Linx.
You are then able to work with this data structure locally.
To give you an idea, we are going to make a request to the Unit Timestamp Converter API (* this API was built and is hosted using Linx).
The API returns date related information in the form of a Unix Timestamp.
To demonstrate using POST
functionality, we are going to submit a response body to the endpoint below:
https://showcase.api.linx.twenty57.net/UnixTime/tounixtimestamp
The Request Body
will contain a field with the name DateTime
and a string value containing a timestamp:
{
"Datetime":"2019/02/11 13:38:00"
}
If successful, a 200 (OK)
response will be returned with the below Response Body
:
{
"UnixTimeStamp":"1549892280"
}
To implement the above functionality in Linx:
-
Create a new function and rename it
PostCurrentTimestamp
. -
Create or Import a new TypeTYP with the name of
CurrentTimestamp
. -
Add a field with the Name of
DateTime
and leave the Type asString
. -
Drag the CurrentTimestampTYP onto the PostCurrentTimestamp function.
-
Expand the local instance’s of the CurrentTimestampTYP Value.
-
For the Value of
DateTime
, we are going to create an expression to format the current timestamp into the correct time format.This is done with the below expression using the
.ToString()
method:=$.System.CurrentDateTime.ToString("yyyy/MM/dd HH:mm:ss")
-
Now that we’ve created and set the local instance of our request body, we need to configure the
CallRESTEndpointFNC to send the correct content.Add a a CallRESTEndpointFNC to the PostCurrentTimestamp function.
-
Set the URL as:
https://showcase.api.linx.twenty57.net/UnixTime/tounixtimestamp
-
Alter the Method to be
POST
. -
Set the Body format as
JSON
.This will automatically serialize the data into the correct format and include the
application/json
Content-Type header. -
For the Body , this will be the payload we want to submit, in our case it is the local instance of the CurrentTimestampTYP.
Reference the
CurrentTimestamp
as the Body.
Debug the function and note how the Request Body
is submitted with the current date stamp.
Re-using data structures
The Response Body
from the request above contains a single field with the name UnixTimeStamp
and is of the type String
. In order to parse the response body text for this field, we need to assign it to a TypeTYP. Our CurrentTimestampTYP is of the same structure , however the field names don’t match i.e. “DateTime” does not map to “UnixTimeStamp”, therefore if we used this it would not map correctly.
We could create a new TypeTYP and reference that, however that will just add more clutter to the Solution Explorer. Instead, we are going to map the fields returned in the response to the use the CurrentTimestampTYP
In Linx, you are able to map the Response Body
to a TypeTYP using type mapping.
This is done using a JSONReaderFNC .
A JSONReaderFNC takes in a StringTYP and has an Result of a TypeTYP. You are able to map fields that appear in the string to the TypeTYP.
In our case, we are going to read the Response Body
string.
The field “UnixTimestamp” will be parsed and its value mapped to the CurrentTimestampTYP.
-
Add the JSONPLG .
-
Add a JSONReaderFNC to the PostCurrentTimestamp function.
-
Set the Json string as the
CallRESTEndpoint.ResponseBody
. -
For the Output type, reference
Project.CurrentTimestamp
.
If you debug the function, you will see there is an output from the JsonReader, however the
DateTime
field is empty.This is because we still need to manually map the fields in the Json string to the CurrentTimestampTYP.
-
Expand the Property map editor.
-
The Name is the field in the text that the value will be extrated from , in this case
UnixTimestamp
. -
The corresponding Property Name will be
DateTime
.
When you debug the function now, note how the JsonReader correctly maps the field:
To use this parsed value, you just need to reference the output of the JsonReader in subsequent functions like:
= "The current Unix timestamp is " + JsonReader.DateTime