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
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.
Finally lest add some test data.
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.
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.
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.
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:
This code will assign value of accept header to variable accept.
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.
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.
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.
great post we need more
Hi, definitely new posts arrive soon