Helping you drive digital innovation
Subscribe
RSS Feed of the Mendix Blog
Thanks for Subscribing

Keep an eye out for Mendix resources coming straight to your inbox.

REST Part II: Publishing Microflows with REST

on June 13, 2014

Share:

Welcome to the second part of our REST Services introduction. In my previous post, we discovered how to consume a REST service. This post explains how to create a REST API that publishes a microflow.

The ShellShare app

In this blog post, we will build ShellShare, a small app that helps you to store and share shell commands: those pesky tiny little things you can’t remember because of all the different flags and acronyms, like gzip -c <filename> > outputfile to zip a file without losing the source file. With this app, you no longer need to Google the same command over and over again. You will be able to browse these shell commands by using the web interface, or by using its REST API. So, let’s get started!

The ShellShare app

We will not dive into the details of building the app’s logic or web interface, since that is basic Mendix knowledge. In this blog post, we will be building the ‘search’ API that takes a search query, optional offset and limit, and returns a list of matching shell commands. The domain model of our app is pretty self-explanatory and looks like this:

ShellShare domain model

Building & publishing the search service

With this domain model in mind, let’s implement the ShellShareApi.search microflow that will be published. A REST published microflow always takes zero or one arguments, which has to be transient (with the exception of microflows that accept filedocuments). This one argument, however, can be arbitrarily complex and should represent all the parameters the service accepts. In our case, there are just three parameters: ‘q’ (for the query), ‘offset’ and ‘limit’.

The return type of the microflow is a list of non-persistable CommandLineView objects. The REST services module doesn’t allow you to publish operations that work with persistent objects to enforce the best practice to not directly expose the inner state of your application to the outer world (the exception to this rule are file documents since they have no transient counterpart). Since these non-persistent objects force you to separate the concerns of state and view, you can always refactor your domain without the side effect that your external API changes. To summarize, this results in the following domain model for our API:

ShellShare API domain model

Let’s take a closer look at the search microflow implementation. The microflow first checks whether a valid search query is provided. If not, a WebserviceException is thrown. Similar to webservices, this type of exception makes sure that the exception message is communicated back to calling client (instead of just stating ‘Internal Server Error’). Next, we execute the search query while taking the optional ‘offset’ and ‘limit’ parameters into account. The final step is to convert the CommandLine objects we retrieved from the database into CommandLineView objects. This allows us to do some post processing before sending the objects over the wire. The REST Services module also provides a utility function to ease this process; copyAttributes copies all similarly named attributes from one object to another.

Finally, we have to make sure the search microflow is published as REST API. To achieve this, we simply create the following After Startup microflow:

Startup microflow of the ShellShare app
The microflow first makes sure the REST Services module is started. Secondly, we register the microflow as published service. For that, we provide the qualified name of the microflow we want to publish, a description and the user role which will be granted access to the service. Since this service should be readable by anyone, we set the security role parameter to ‘*’. (In the next blog post we will take a closer look at authentication). Since we are all set now, let’s fire up the app!

Testing the service

After the app has started, we can browse* to <app-url>/rest/ to inspect our published services. By clicking on the search service, we get a generated description of our service with endpoints, HTTP methods and json-schemas describing the input and output parameters. The Rest Services module tries to mix and match input data as much as possible, so our service can be invoked by using both POST or GET requests, with data that is provided in the form of URL parameters, form-encoded parameters, multi-part data, binary data or json data. The output of the service is either rendered in json, HTML or XML. The actual output depends on the accept type. So, we can directly invoke a service manually using our browser. Let’s take a quick look!

HTML preview of the search service

In the same way, we can make this request by using curl:

$ curl -H "Accept:application/json" https://shellshare.mendixcloud.com/ws-doc/search?q=version%20control
[{
 "author": "Michel Weststrate",
 "title": "Enables git-based version control in a Mendix Project",
 "isprivate": false,
 "description": "Run the command in the ....",
 "labels": [
 {"name": "mxgit"},
 {"name": "git"},
 {"name": "mendix"}
 ],
 "command": "mxgit --install"
}]

If you want to consume this service in another Mendix project, simply invoking the REST java action getCollection on the endpoint* https://shellshare.mendixcloud.com/ws-doc/search would suffice.

Summary

In conclusion, it is very easy to publish a REST service since only a few steps are needed:

  1. Setup a domain model for your input and output arguments
  2. Implement the microflow that needs publishing
  3. Register the service by invoking the RestServices.CreateMicroflowService microflow.

That’s all! Next time we will discover how to build a complete, Restful CRUD API around entities in your domain model.

Have fun and don’t forget to contribute to the GitHub project!

 

 

* Note that in sandboxes the REST module will publish its services under /ws-doc/. In any other environment the REST module will publish its services under /rest/.

Subscribe to Our Blog

Receive Mendix platform tips, tricks, and other resources straight to your inbox every two weeks.

RSS Feed of the Mendix Blog

About Michel Weststrate

Michel is a 30 years old software developer graduated at the Delft University of Technology and currently working as lead developer at Mendix / Sprintr. Michel is happily married to Elise and father of two daughters. In his rare free time, you can find him reading or writing even more software.

  • Mitchel Mol

    Great tutorial, there is just a small problem with your example sandbox app the API documentation urls are all pointing to https://shellshare.mendixcloud.comws-doc/… Note the missing / after .com and before ws-doc. You might want to fix that.

  • Thanks for reporting! The status of this issue can be tracked at https://github.com/mendix/RestServices/issues/41

  • Srinivas Hasti

    Nice article. How does security work ? We are building a secure web site in Mendix and want to leverage same security model for entities/microflows exposed in REST way. We are looking to build a hybrid mobile app that accesses those REST services. So we need a way to login the user for any 401 responses. Is there a login post url that can be used ? Our mobile app can handle cookies, so once user logs in we can act like a browser to send cookies back so we can call other REST services. I appreciate your thoughts on the topic.

  • Michel Weststrate

    REST reuses the Mendix security models. Users are authenticated either by sending Basic authentication credentials, or by using cookies. These are the same cookies as set up by the mendix client. So you could reulse the login post url of the Mendix client system itself (just log on to the Mendix app with your browsers network debugger tool open).