MxBlog

Howto - using Mendix app-services

This blogpost will show you how you can create a Mendix app-service. In a followup i'll describe how you can consume the functionality provided in this app-service.

Example use of the app-service

The goal is to implement an app-service that will provide address information based on zipcode and house number. The follownig page shows an example how this can be used. In this form you have two fields where you can enter Postcode and housenumber. Using the app-service the non-editable fields address, city and province will be set.

Form

Implementing the App-Service

The following screenshot shows you the outline of the Mendix project. The customers module will be consuming the app-service, the AddressValidator module contains the app-services that will be published. Usually these will be implemented in different Mendix applications, but for this example i have combined them into one project.

Project Explorer

The overall flow of the application is illustrated in the following sequence diagram. This post focusses on the last three objects in the diagram, which implement the getAddress app-service.

Service flow

The app-service has one non-persistent entity for input (Postcode), and one for output (Address).

Domain model

GetAdres is the microflow that will be published in the app-server. The microflow uses a Java Action to call an external service to do the actual work. This means that you are really using 2 services. This has some performance impact, but will result in a user friendly way to call the service through an app-service.

Microflow - getAddress

The postcodeapi.nu REST service will be called from a custom Java action, which is defined in Mendix as follows:

Java Action

The actual implementation of the Java action. It uses the unirest library to do the call.

package addressvalidator.actions;

import addressvalidator.proxies.Address;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mendix.core.Core;
import com.mendix.systemwideinterfaces.core.IContext;
import com.mendix.systemwideinterfaces.core.IMendixObject;
import com.mendix.webui.CustomJavaAction;
import org.json.JSONObject;

/**
 *
 */
public class PostcodeApi extends CustomJavaAction<IMendixObject> {
    private String PostcodeParameter1;
    private String HouseNumber;

    public PostcodeApi(IContext context, String PostcodeParameter1, String HouseNumber) {
        super(context);
        this.PostcodeParameter1 = PostcodeParameter1;
        this.HouseNumber = HouseNumber;
    }

    @Override
    public IMendixObject executeAction() throws Exception {
        // BEGIN USER CODE
        String apiKey = "<INSERT API KEY FOR API.POSTCODEAPI.NU>";
        HttpResponse<JsonNode> jsonResponse = Unirest.post("http://api.postcodeapi.nu/"
                + this.PostcodeParameter1 + "/" + this.HouseNumber)
                .header("accept", "application/json")
                .header("Api-Key", apiKey)
                .asJson();
        Core.getLogger("PostcodeAPI").info("json = " + jsonResponse.getBody().toString());
        Address address = new Address(super.getContext());
        JSONObject resource = jsonResponse.getBody().getObject().getJSONObject("resource");
        address.setStreet(resource.getString("street"));
        address.setCity(resource.getString("town"));
        address.setPostcode(resource.getString("postcode"));
        address.setHouseNumber(resource.getString("house_number"));
        address.setLongitude(resource.getString("longitude"));
        address.setlatitude(resource.getString("latitude"));
        address.setProvince(resource.getString("province"));
        return address.getMendixObject();
        // END USER CODE
    }

    /**
     * Returns a string representation of this action
     */
    @Override
    public String toString() {
        return "PostcodeApi";
    }

    // BEGIN EXTRA CODE
    // END EXTRA CODE
}

Now that we have the microflow, we can publish it as an app-service. The first time you do this you need to add a published app-service to your module.

Publish App-Service

In the general tab you can specify some generic information about the app-service

App service general

The actions tab lists all the microflows that are provided by the app-service. This basically is the Api of your app-service.

App service actions

Finally a tab where you can specify authentication settings.

App service settings

Also on this tab is a Expert Mendix Service Definition file, which serves the same purpose as a WSDL file: it is an interface description of your app-service. It actually contains a WSDL document.

We need this msd file, as we are not going to deploy the app-service separately. You can share this msd file with people who want to consume your app-service. In our case we will use this msd file to consume the app-service in a different module in the same application. From a performance point of view, this doesn't make much sense, but it makes for a nice example.

Mendix service definition file

Next we'll see how you can use the app-service.