Example REST client configurations
This page presents examples of REST client definitions that leverage the possibilities of the Magnolia REST Client module.
As this page focuses mainly on REST client configurations, below we deal with template definitions and template scripts only marginally.
| See also the Hello Magnolia - with content via REST tutorial page containing an additional and easy to configure scenario. | 
Case 1: Simple configuration
In this case, a REST client is configured to send a request to the /wonders path of the https://www.world-wonders-api.org/v0/ endpoint to get a list of selected wonders of the world.
Client configuration
The client is called wonders, its name is derived from the configuration file’s name.
The REST call is named allWonders in this definition.
baseUrl: https://www.world-wonders-api.org/v0/
restCalls:
  allWonders:
    method: GET
    entityClass: com.fasterxml.jackson.databind.JsonNode
    path: /wondersComponent template script
Example component script that renders the list of wonders.
[#assign response = restfn.call("wonders", "allWonders")]
<h2>Wonders</h2>
<ul>
[#list response.elements() as wonder]
    <li>${wonder.get("name").textValue()}</li>
[/#list]
</ul>Case 2: Configuration with a security scheme
If the REST API service needs an authentication of a REST call, you can configure a security (authentication) scheme for it under the securitySchemes
node. You can use scheme types basic and bearer, which are available out of the box in the REST client module.
For an example with the basic scheme, see basic security scheme.
Below are more example configurations.
Bearer token with expiry duration
Example configuration of a client called bearer-security utilizing the bearer security scheme and an expiration limit. The scheme’s configuration is defined under the bearerTokenWithExpiryDuration node, the authentication call is configured under authenticateWithDurationAsLong.
baseUrl: http://localhost:${wiremockPort}
securitySchemes:
  bearerTokenWithExpiryDuration:
    $type: bearer
    restClientName: bearer-security
    restCallName: authenticateWithDurationAsLong
    tokenJsonPath: $.access_token
    expiry:
      $type: duration
      expiryJsonPath: $.expires_in
      expiryTimeUnit: SECONDS
restCalls:
  getDataWithBearer:
    method: GET
    entityClass: com.fasterxml.jackson.databind.JsonNode
    path: /getDataWithBearer
    securityScheme: bearerTokenWithExpiryDuration
  authenticateWithDurationAsLong:
    method: POST
    entityClass: com.fasterxml.jackson.databind.JsonNode
    path: /oauth2/token
    headers:
      Content-Type: application/x-www-form-urlencoded
      X_Test_Expiry_Type: DURATION_AS_LONGOAuth2 bearer security scheme with expiry duration
Example configuration of a client called knowledgeSource also utilizing the bearer security scheme and an expiration limit. The scheme’s configuration is defined under the oauth2 node. The authentication call is configured under authenticate in a separate knowledgeSourceAuth.yaml configuration file.
| This example showcases a situation in which you are using a third-party authentication service for your REST calls. In other words, the authentication URL is different from the service URL. In this particular example configuration, the domain where the token is served from is  | 
baseUrl: https://api.example.com/systems/client/v1
securitySchemes:
  oauth2:
    $type: bearer
    restClientName: knowledgeSourceAuth
    restCallName: authenticate
    tokenJsonPath: $.access_token
    expiry:
      $type: duration
      expiryJsonPath: $.expires_in
      expiryTimeUnit: SECONDS
restCalls:
  getUser:
    method: get
    entityClass: com.fasterxml.jackson.databind.JsonNode
    path: /users/123
    securityScheme: oauth2
  getUsersInOrg:
    method: get
    entityClass: com.fasterxml.jackson.databind.JsonNode
    path: /organisations/abc-123/users
    securityScheme: oauth2baseUrl: https://login.example.net/089a6470-d3a7-46a4-8852-74c0c698c729
restCalls:
  authenticate:
    headers:
      Content-Type: "application/x-www-form-urlencoded"
    path: /oauth2/v2.0/token
    method: post
    entityClass: com.fasterxml.jackson.databind.JsonNode
    body: 'client_id=62336501-fbe2-4fbe-9bba-1b0b4a8c8573&client_secret=Sih8Q~tW-Sdnxc4tdvECHfwYGIJ6jaP4TeKfzcVr&grant_type=client_credentials&scope=https%3A%2F%2Fapi.app.example.com%2Fsgc%2F.default'Case 3: Configuration with a JavaScript model
This case makes use of a REST client called books and a JavaScript model called search. The model invokes the configured searchByIsbn call that queries the https://openlibrary.org/dev/docs/api/read API with a request for a record of a book identified by the ISBN 13 number.
The component template script then renders the book’s title, number of pages and its cover image (if available).

Client configuration
baseUrl: http://openlibrary.org/api
restCalls:
  searchByIsbn:
    method: get
    entityClass: java.lang.String
    path: /volumes/brief/isbn/{isbn}.json
    defaultValues:
      isbn: 978-3-16-148410-0| The pathproperty uses the{isbn}template, where the JavaScript model injects the value submitted by the user in the search field. | 
Component template script
[#assign isbn = ctx.getParameter("isbn")!]
[#assign isSubmitted = ctx.getParameter("submit")?has_content?then(true, false)]
[#if isbn?has_content && isSubmitted]
    [#assign result = model.search(isbn)]
[/#if]
<h2>Search books by isbn13</h2>
<p>For example: 9780261103252, 9780582517349</p>
<div style="margin:10px">
    <form method="get">
        <p>
            <label for="isbn">Isbn</label>
            <input type="text" name="isbn" />
        </p>
        <input type="submit" name="submit" value="Search" />
    </form>
[#if result?has_content]
    <p>Title: ${result.title}</p>
    <p>Number of pages: ${result.number_of_pages}</p>
    <img src="${result.cover.large}" alt="Cover"/>
[/#if]
</div>JavaScript
var BookModel = function () {
    var restClient = restClientFactory.createClientIfAbsent(restClientRegistry.getProvider("books").get());
    this.search = function (isbn) {
        var result = restClient.invoke("searchByIsbn", { isbn: isbn});
        var data = JSON.parse(result.getEntity());
        if (data && data.records) {
            var keys = Object.keys(data.records);
            return data.records[keys[0]].data;
        }
        return null;
    }
};
new BookModel();Case 4: Configuration using an OpenAPI schema
The benefit of a configuration using an OpenAPI schema is that all that is required to configure a REST client is reduced just to two properties, class and schemaUrl.
- 
For the class, you useinfo.magnolia.openapi.client.OpenApiRestClientDefinition.
- 
For the schemaUrl, you provide a link to an existing definition (file or URL) complying with the OpenAPi v3 specification.
Client configuration
class: info.magnolia.openapi.client.OpenApiRestClientDefinition
schemaUrl: https://en.wikipedia.org/api/rest_v1/?specComponent template script
[#assign aDateTime = .now]
[#assign results = restfn.call("wikipedia", "onThisDay", {"type":"all", "mm":aDateTime?string["MM"], "dd":aDateTime?string["dd"]}) ] (1)
<h2>What happened on ${aDateTime?string["MMMM"]} ${aDateTime?string["dd"]} in the past?</h2>
[#list results.get("selected").elements() as event]
<p>
  ${event.get("text").textValue()} (${event.get("year").intValue()?c}) (2)
</p>
[/#list]
<p>(Source: en.wikipedia.org)</p>| 1 | The alias onThisDayis used to target the endpoint path since the alias is defined in the schema. If this weren’t the case, you can always refer to a call name using the following pattern:method:/path/pathAction. | 
| 2 | At the end of the directive, the cFreeMarker builtin is used to render theintValue()for the year without formatting for human audience, for example as2019rather than2,019. | 
After passing the template values for type, month and date, the component displays a list of notable events that happened on the given day at some point in the past, for example:
