HTTP GET method’s simple design has been published in previous article. We designed account service using RAML and Open API specifications. It is time, now, to implement that service so our potential users could consume it. To implement the service I use new Mule’s Design Center available on Anypoint Platform. To follow my steps you wouldn’t need to download any software on your PC at all. On the other hand Anypoint Studio is the main IDE to design Mule’s services so I will not omit this tool. Within it I show the possibilities of APIkit message processor. During following examples I will use newest Mule 4.1.

Mule version

Tools

I am going to use following tools:

  • Design Center to design service online
  • Anypoint Studio to design service offline

Preparation

Our service should manage some data. Therefore I have decided to use MongoDB as a storage and its RESTful interface to interact with database. You can create free account on mLab website. In order to create free database follow this steps:

  • Chose sandbox from available Plan Types
  • On the next screen select AWS Region
  • Next name the database
  • On the next screen you should see Order Confirmation like below. Total Price should be Free.

Once your database is created you may add collections and documents into them. Please add collection called accounts and add two documents. You should see Collection summary similar to the one attached below:

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 following link. Design Center is available since July and accessible from Anypoint Platform.

Design Center’s main screen

There you can design mule applications, APIs and API fragments. We already used API Specification option to create API.raml file with service description using RAML specification. After you click Mule Application you only are ask to submit application name. After that you should be presented with the following screen:

Design canvas

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

Implement get accounts’ list

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

Get accounts flow

 

First we need to define HTTP Listener connector. By default it will allow connection on port 8081 with empty path. However our AccountAPI 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 attributes property. It will contains inbound and outbound properties. All properties related to sent payload will be available within one structure. Here is an example how do we get header:

message.inboundProperties.accept
attributes.headers.accept

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

As we would like to return two different representations such as JSON and XML we need to preserve value sent within Accept header. We will do it using Transform component saving this value to 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:

%dw 2.0
output application/java
---
attributes.headers.accept
This code will assign value of accept header to variable accept.
HTTP Request calling MongoDB’s interface

Next it is time to call external system. To get all accounts we would need to send GET request under following URI https://api.mlab.com/api/1/databases/yourDBName/collections/accounts?apiKey=yourAPIkey. To do it I will use HTTP Request component. First we need to fill Configuration. We need to specify:

  • protocol to be HTTPS
  • host to be call like api.mlab.com
  • base path if necessary for example /api/1/databases/dbname/

Component needs to be configured as well. To perform get we need to specify method and URI to call in Path property. After that we have a choice flow control. We check if accepted was XML using DataWeave expression vars.accept==’application/xml’. For both paths I have attached transformers. First transformer to XML is as following:


%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 (value0, index0) -> {
  name: value0.name,
  surname: value0.surname,
  role: value0.role,
  rank: value0.rank,
  login: value0."_id"
})


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

Implement get account by login

Here is complete flow that realize the function of getting account by login from 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 response’s representation. After that we perform call to MongoDB‘s rest interface to get the account. When we receive the response, we chose, using Choice component, whether client accepts XML or something else. For each path we perform simple mapping, as items structure is slightly different in database in comparison to returned data model.

Get account by login

 

First we need to define HTTP Listener connector. By default it will allow connection on port 8081 with empty path. However our AccountAPI 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}. Next transformation is exactly the same as in previous sub-chapter.

Variables

In Mule 4 variables are accessible by vars keyword. flowVars is no longer available.

vars.accept = 'application/xml'

Next it is time to call external system. To get account by id we would need to send GET request under following URI https://api.mlab.com/api/1/databases/yourDBName/collections/accounts/{login}?apiKey=yourAPIkey. To do it I will use HTTP Request component.  As you can see below path has been provided with {login} placeholder. HTTP Request component will fill this placeholder using defined URI parameters. They are available below in Request section. We create login parameter that is filled using expression attributes.uriParams.login.

Get request with URI parameter

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

Anypoint Studio

APIKit

APIkit works for SOAP and REST services. This is the component that creates skeleton of the projects’s flows based on service contract. Respectively for SOAP is used WSDL file and for REST raml file. Generated skeleton contains:

  • main flow with APIkit Router responsible for routing incoming message to proper private flow
  • default error handling
  • API console with online user friendly API view
  • private flows for each defined operation

APIkit Router not only routes messages but also validates incoming content. So if client sends payload that is not valid against schema 400 bad request will be returned with description. What is more each URI parameter will be extracted to variable so you won’t need to look for it within uriParams collection.  Name of the variable will be exactly the same as defined in raml definition for example vars.login.

Private flow’s name will contain:

  • http method
  • path if URI parameters are present will be embraced with brackets
  • global APIkit’s name
get:\accounts:accounts-api-config
get:\accounts\(login):accounts-api-config

We got here two get methods. The first one is for /accounts path and the second one for /accounts/{login} with login placeholder. Both paths are for accounts-api-config configuration.

APIKit come in handy

While in Design Center we needed to create service implementation manually in Anypoint Studio using APIkit we can boost project’s implementation. Here is what we got after project’s creation:

Project created using APIkit

I created two mule flows:

  • global
  • accounts-impl

First contains global configuration like HTTP listener and request. The second one contains operations’ implementation. I find it to be a good practice to keep that structure.

Implementation

Logic is the same as described in Design Center section above. Only user interface is different. However I found it easier and quicker to implement service using Anypoint Studio

Summary

Design Center has less message processors to use however to design simple services it is good enough. I was disappointed that I could not import previously designed API and create easily project that implements this API. I thing this tool should be more integrated.

APIkit is a great tool to create project skeleton. Using it we are able to implement service quicker. What is more validation and metadata are provided out of the box. I recommend this to implement both new SOAP and REST services.

Source Code

Code is available on GitHub.

Simple GET operations Design Center vs APIKit
Tagged on:             

2 thoughts on “Simple GET operations Design Center vs APIKit

Leave a Reply

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