Implement simple GET operations using Flow Designer

Last Updated on 02/05/2021 by Patryk Bandurski

HTTP GET method’s simple design has been published in a previous article. I designed the account service using the RAML specification. It is time, now, to implement that service so our potential users could consume it. To implement the service I use Flow Designer available on Anypoint Platform. To follow my steps you wouldn’t need to download any software on your PC at all.

Preparation

Our service should manage some data. Therefore I have decided to use MongoDB as storage. You can create a free account on the mongodb website. In order to create a free database follow these steps:

  • Click the Build a Cluster
  • Pick Shared Clusters from the available options
  • On the next screen select AWS provider and AWS Region
  • Next name the cluster
  • Confirm creation by clicking Create Cluster button
Free tier mongodb cluster
Free tier mongodb cluster

Once your cluster is created you may add collections and documents into them. Click Collections and Add My Own Data buttons. Give the database name and collection name – like on the screen below.

Creating first dynamodb collection
Creating first dynamodb collection

Finally lest add some test data.

Test data for accounts table
Test data for accounts table

In order to activate access to your database by REST interface you need to follow instructions available on mLab site.

Design Center

If you do not have an account on Anypoint Platform you can create one, free of charge, under the following link. Go to the Design Center and click + Create new. From the drop-down pick New Mule App. You will be prompted to provide the application name. Let’s call it the Accounts SAPI APP. Hit Create App button.

Flow Desinger's initial empty canvas
Flow Desinger’s initial empty canvas

New Flow is the default flow that is created for the new mule application. On the left-hand side of the canvas, you can see the project structure divided into three different parts like Flows, reusable configuration, and data types. You can use plus signs to add new components. You can not drag elements on the canvas, but you can maximize and minimize components and add event processors by the plus sign. If you decide to add a component between two already defined, you can add it without a problem.

Implement get accounts’ list

Here is the complete flow that realizes the function of getting all accounts from the MongoDB database. We define an HTTP listener that is listening for the GET calls sent under /accounts path. Then we preserver Accept header within variable called accept. This variable will be used to choose the response’s representation. After that, we perform a call to MongoDB‘s interface to get the list of all accounts. When we receive the response, we chose, using the Choice component, whether the client accepts XML or something else. For each path, we perform simple mapping, as the structure of the item is slightly different in the database in comparison to the returned data model.

Retrieving all accounts from DynamoDB accounts table using Flow Designer
Retrieving all accounts from DynamoDB accounts table using Flow Designer

First, we need to define the HTTP Listener connector. By default, it will allow connection on port 8081 with an empty path. However, our Account API specified that we should hit under /accounts path. In order to do it in HTTP Listener, we do specify Path to be /accounts.

New mule message structure

In Mule 4 message structure has been simplified. It contains only payload and attributes. The main difference is the attributes property. It contains inbound and outbound properties. All properties related to the sent payload are available within one structure. Here is an example of how do we get a header:
message.inboundProperties.accept
attributes.headers.accept

In the first line, I depicted the previous approach. In the second line, we see the new Mule 4 syntax.

As we would like to return two different representations such as JSON and XML we need to preserve the value sent within Accept header. We do it using the Set Variable component saving this value to the variable. Transformer by default has payload transformation and we need another one. Click Add transformation button. From types list select vars (variables) and place name like accept. Then remove payload transformation form the list, so only one transformation persist. In the script paste following code:

Set Variable configuration to store accept header. attributes["headers"].accept
Set Variable configuration to store accept header

This code will assign value of accept header to variable accept.

MongoDB find document operation looking for all accounts with all fields
MongoDB find document operation looking for all accounts with all fields

Next, it is time to call an external system. To get all accounts we would need to use the Find Documents operation. To make it work you need to configure the connection. You need to give following values:

  • Connection Name – DemoDB
  • Connection Type – Connection String – Take the connection string from your MongoDB’s cluster view

In the operation configuration, you need to specify the Collection name – in our case it is accounts, and the fields to return. As you can see on the screen above, I put a single comma sign. Based on the MongoDB connector documentation it will result in receiving all the fields.

After the MongoDB operation, I put a choice component. We check if consumer wants XML output using DataWeave expression vars.accept=='application/xml'. For both paths, I have attached the message transformations. The first one converting value XML is as follows:

%dw 2.0

output application/xml
---
accounts:
  account: payload map ({
    name: $.name,
    surname: $.surname,
    role: $.role,
    rank: $.rank,
    login: $.'_id'
})

The default path has follwing transformation:

%dw 2.0
output application/json
---
  (payload map ({
    name: $.name,
    surname: $.surname,
    role: $.role,
    rank: $.rank,
    login: $.'_id'
}))

Worth noticing are lines 11 and 10 where we put _id field into login. The field name may not start with an underscore character that is the reason why it was put into quotation marks.

Implementing get account by login

Here is the complete flow that realizes the function of getting an account by login from the MongoDB database. We define HTTP listener that is listening for GET calls sent under /accounts/{login} path. Where {login} is placeholder for login name. Then we preserver Accept header within variable called accept. This variable will be used to choose the response’s representation. After that, we perform a call to MongoDB to find the account. When we receive the response, we chose, using the Choice component, whether the client wants an XML response. For each path, we perform simple mapping, as the structure of the item is slightly different in the database in comparison to the returned data model.

Get account by login

First, we need to define the HTTP Listener connector. By default, it will allow connection on port 8081 with an empty path. However, our Account API specified that we should hit under /accounts/{login} path. In order to do it in HTTP Listener, we do specify Path to be /accounts/{login}. The next Set Variable component is exactly the same as in the previous section.

Next, it is time to call an external system. To get an account by id we would need to use the Find Documents operation with Query.  As you can see below path has been provided with {login} placeholder. To access login from URI I use attributes.uriParams.login expression.

Find Documents operation with Query specified
Find Documents operation with Query specified

Choice flow control is the same as in the flow get accounts. However, transformations are slightly different because we only need to transform a single record, unlike earlier the whole array.

Summary

Design Center has fewer message processors to use however to design simple services it is good enough. It is also the best tool for quick prototyping. Of course, this won’t be my first choice as I got used to Anypoint Studio and more sophisticated integration designs. I think the tool is dedicated more to analysts/architects as it is less code-centric, of course, basic DataWeave knowledge may be required :).

Source Code

Exported code from Flow Designer – without secure properties – is available on GitHub.

Implement simple GET operations using Flow Designer

2 thoughts on “Implement simple GET operations using Flow Designer

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top