Contact Us 1-800-596-4880

Converting a Mule Project to an APIkit Project

If you choose a backend-first design approach for Mule projects and applications that contains business logic, you can convert them into an APIkit project and expose them as REST services. Use one of these approaches:

Consider the size and complexity of the application when deciding on the best approach.

The examples for these approaches are based on the following Mule application that retrieves users from a database:

<mule>
    <http:listener-config name="HTTP_Listener_config">
		<http:listener-connection host="0.0.0.0" port="8081" />
	</http:listener-config>
	<db:config name="Database_Config">
		<db:my-sql-connection host="localhost" port="3306" user="admin" password="admin" database="usersdb" />
	</db:config>
	<flow name="GET-Users-FLOW">
		<http:listener config-ref="HTTP_Listener_config" path="/users"/>
		<db:select config-ref="Database_Config">
			<db:sql ><![CDATA[SELECT * FROM USERS]]></db:sql>
		</db:select>
	</flow>
	<flow name="GET-User-By-Id-FLOW">
		<http:listener config-ref="HTTP_Listener_config" path="/userById" />
		<db:select config-ref="Database_Config" >
			<db:sql ><![CDATA[SELECT * FROM USERS WHERE :userIdParameter == userID]]></db:sql>
			<db:input-parameters ><![CDATA[#[{userIdParameter: attributes.queryParams.id}]]]></db:input-parameters>
		</db:select>
	</flow>
</mule>

Before You Begin

To define the API specification for your service, see Design Your API Specification When Building, Implementing, and Testing a REST API. To illustrate this example, create or copy the API specification and JSON example used in that workflow to the /src/main/resources/api folder.

Manual Approach

Follow these steps to configure a functional router for your existing flows manually.

Step 1: Create a Main Flow

Within the APIkit project, create a main flow that serves as the entry point:

  1. Drag the following components from the Mule palette to the canvas:

    • An HTTP Listener source as a flow source

    • An APIkit Router operation within the flow process

  2. In the properties editor for HTTP Listener in Connector Configuration, select the existing HTTP_Listener_Config.

  3. Specify a listener path for the APIkit router by entering /api/ in *Path.

  4. In the properties editor for the APIkit router, in Router Configuration, click Add to create a new configuration.

    The Global Element Properties wizard appears.

  5. In API Definition, select the api/api.raml path.

  6. Accept the configuration.

  7. Delete HTTP Listener from GET-Users-FLOW.

  8. Delete HTTP Listener from GET-User-By-Id-FLOW.

<mule>
    <apikit:config outboundHeadersMapName="outboundHeadersMapName" httpStatusVarName="httpStatus" name="Router" api="api/api.raml" />
    <http:listener-config name="HTTP_Listener_config">
		<http:listener-connection host="0.0.0.0" port="8081" />
	</http:listener-config>
	<db:config name="Database_Config">
		<db:my-sql-connection host="localhost" port="3306" user="admin" password="admin" database="usersdb" />
	</db:config>
    <flow name="apiFlow">
		<http:listener config-ref="HTTP_Listener_config" path="/api/*"/>
		<apikit:router config-ref="Router"/>
	</flow>
	<flow name="GET-Users-FLOW">
		<db:select config-ref="Database_Config">
			<db:sql ><![CDATA[SELECT * FROM USERS]]></db:sql>
		</db:select>
	</flow>
	<flow name="GET-User-By-Id-FLOW">
		<db:select config-ref="Database_Config" >
			<db:sql ><![CDATA[SELECT * FROM USERS WHERE :userIdParameter == userID]]></db:sql>
			<db:input-parameters ><![CDATA[#[{userIdParameter: attributes.queryParams.id}]]]></db:input-parameters>
		</db:select>
	</flow>
</mule>

Step 2: Map API Resources and Actions to Flows

By default, each APIkit flow adheres to a naming convention for routing purposes, characterized by the following pattern:

action:\resource[:content-type][:config-name]

Name Description

action

HTTP method

resource

HTTP resource

content-type

Payload content-type (optional)

config-name

APIkit router configuration name (optional)

To retain the original flow names and map each API resource and action to them, override this behavior by following these steps:

  1. Select APIkit Router to open the Properties Editor.

  2. In Router configuration, click Edit.

    The Global Element Properties wizard appears.

  3. In Mappings, click Add to create a new mapping configuration.

    The New Mapping dialog appears.

  4. Use the drop-down to map the resources to actions.

    • In Resource, select /users.

    • In Action, select Get.

    • In Flow, select GET-Users-FLOW.

    • Click OK.

  5. In Mappings, click Add.

    The New Mapping dialog appears.

  6. Use the drop-down to map the resources to actions.

    • In Resource, select /users/userbyid.

    • In Action, select Get.

    • In Flow, select the flow that contains the get users action: GET-User-By-Id-FLOW.

    • Click OK.

<mule>
    <apikit:config outboundHeadersMapName="outboundHeadersMapName" httpStatusVarName="httpStatus" name="Router" api="api/api.raml" >
		<apikit:flow-mappings >
			<apikit:flow-mapping resource="/users" action="get" flow-ref="GET-Users-FLOW" />
			<apikit:flow-mapping resource="/users/userbyid" action="get" flow-ref="GET-User-By-Id-FLOW" />
		</apikit:flow-mappings>
	</apikit:config>
    <http:listener-config name="HTTP_Listener_config">
		<http:listener-connection host="0.0.0.0" port="8081" />
	</http:listener-config>
	<db:config name="Database_Config">
		<db:my-sql-connection host="localhost" port="3306" user="admin" password="admin" database="usersdb" />
	</db:config>
    <flow name="apiFlow">
		<http:listener config-ref="HTTP_Listener_config" path="/api/*"/>
		<apikit:router config-ref="Router"/>
	</flow>
	<flow name="GET-Users-FLOW">
		<db:select config-ref="Database_Config">
			<db:sql ><![CDATA[SELECT * FROM USERS]]></db:sql>
		</db:select>
	</flow>
	<flow name="GET-User-By-Id-FLOW">
		<db:select config-ref="Database_Config" >
			<db:sql ><![CDATA[SELECT * FROM USERS WHERE :userIdParameter == userID]]></db:sql>
			<db:input-parameters ><![CDATA[#[{userIdParameter: attributes.queryParams.id}]]]></db:input-parameters>
		</db:select>
	</flow>
</mule>

Scaffolding Approach

Follow the process at Before You Begin. When completed, include an alternative workflow for scaffolding your API specification.

With this approach, you get the APIkit router configuration, error handler, and console flow out of the box. You also get a flow that maps each resource.

Step 1: Scaffold Your API Specification

Scaffold your API to auto-generate the main, console, and resources flows:

  1. In Package Explorer, right-click /src/main/resources/api/api.raml.

  2. Select Mule.

  3. Click Generate Flows from Local REST API.

A new XML file with the same name as the API is created. This file contains the scaffolded flows.

Step 2: Reference Flows

Do either of the following:

  • Delete the scaffolded flows for each resource and map the original flows as described in Step 2: Map API Resources and Actions to Flows.

  • Remove all operations from the scaffolded flows and add a flow reference that contains the removed operations. By choosing this option, you introduce an additional layer of indirection because you reference all flows to the flow that has the operations, and such indirection can be inconvenient in some scenarios.

<mule>
...
    <flow name="get:\users\userbyid:api-config">
		<flow-ref name="GET-User-By-Id-FLOW"/>
    </flow>
    <flow name="get:\users:api-config">
		<flow-ref name="GET-Users-FLOW"/>
    </flow>
</mule>
  • Transfer the content of the existing flows to the scaffolded flows that adhere to the routing naming convention. If the application is large, performing these modifications can be a laborious task.

<mule>
...
    <flow name="get:\users:api-config">
		<db:select config-ref="Database_Config">
			<db:sql ><![CDATA[SELECT * FROM USERS]]></db:sql>
		</db:select>
	</flow>
	<flow name="get:\users\userbyid:api-config">
		<db:select config-ref="Database_Config" >
			<db:sql ><![CDATA[SELECT * FROM USERS WHERE :userIdParameter == userID]]></db:sql>
			<db:input-parameters ><![CDATA[#[{userIdParameter: attributes.queryParams.id}]]]></db:input-parameters>
		</db:select>
	</flow>
</mule>

Test Your API

Now that your new project is set up, you are ready to test your API.