---
schema_version: "1"
id: 22be20deef8652064ec9756c838524c2400bd614f640a44acbd157b0baf6147d
title: Migrating an APIkit-based Application
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/mule-runtime/4.4/migration-example-complex.md
canonical_url: https://docs.mulesoft.com/mule-runtime/4.4/migration-example-complex
source_site: docs.mulesoft.com
content_type: documentation
content_hash: 8c909de1632803c02141321c625bcc1d2546fea915e42af0ee74bd85a71782de
description: MuleSoft Documentation Site
release: "4.4"
latest: false
---
# Migrating an APIkit-based Application

This example covers the necessary steps for successfully migrate an APIkit-based application from Mule 3 to Mule 4. The following REST API performs CRUD (create, read, update and delete) operations over a MySQL database.

![api-main in Studio 6](/mulesoft/current/en-us/mule-runtime/4.4/_images/m3-apikit-based-example-main.png)

![api-console in Studio 6](/mulesoft/current/en-us/mule-runtime/4.4/_images/m3-apikit-based-example-console.png)

![get:/product:api-config flow in Studio 6](/mulesoft/current/en-us/mule-runtime/4.4/_images/m3-apikit-based-example-get-products.png)

![get:/product/{id}:api-config flow in Studio 6](/mulesoft/current/en-us/mule-runtime/4.4/_images/m3-apikit-based-example-get-product-id.png)

![post:/product:application/json:api-config flow in Studio 6](/mulesoft/current/en-us/mule-runtime/4.4/_images/m3-apikit-based-example-post-product.png)

![delete:/product/{id}:api-config flow in Studio 6](/mulesoft/current/en-us/mule-runtime/4.4/_images/m3-apikit-based-example-delete-product.png)

![put:/product/{id}:application/json:api-config flow in Studio 6](/mulesoft/current/en-us/mule-runtime/4.4/_images/m3-apikit-based-example-put-product.png)

![api-apiKitGlobalExceptionMapping flow in Studio 6](/mulesoft/current/en-us/mule-runtime/4.4/_images/m3-apikit-based-example-globalexceptionmapping.png)

## [](#migrating-property-placeholders)Migrating Property Placeholders

Mule 4 supports property placeholders either as `.yaml` or `.properties` configuration files.

1. Create a folder with the name `config` under `/src/main/resources` project directory.
2. Create a configuration file with the name `configuration.yaml` inside the newly created config folder.
3. Migrate property placeholders from `.properties` to `.yaml` format.
    
    configuration.properties
    
    http.host=0.0.0.0
    http.port=8081
    
    mysql.password=pa$$w0rd
    mysql.port=3306
    mysql.user=admin
    mysql.database=products
    mysql.host=corp.services.com
    
    autodiscovery.api.version=1.0.0:1762946
    autodiscovery.api.name=groupId:com.mulesoft.retailer.manufacturingit.apis:assetId:product-api-database
    
    anypoint.platform.client\_id=1f702j71hu9z2x88v9vd19v7h248s589
    anypoint.platform.client\_secret=87v8V47668701Dd574B0531255d6287d
    
    configuration.yaml
    
    http:
      host: "0.0.0.0"
      port: "8081"
    
    mysql:
      password: "pa$$w0rd"
      port: "3306"
      user: "admin"
      database: "products"
      host: "corp.services.com"
    
    autodiscovery:
      api:
        name: "groupId:com.mulesoft.retailer.manufacturingit.apis:assetId:product-api-database"
        version: "1.0.0:1762946"
    
    anypoint:
      platform:
        client\_id: "1f702j71hu9z2x88v9vd19v7h248s589"
        client\_secret: "87v8V47668701Dd574B0531255d6287d"
4. Replace the standard Spring element `<context:property-placeholder>` with the new Global Element `configuration-properties`.
    
    Configuration XML for Property Placeholders in Studio 6.
    
    ```xml
    <context:property-placeholder location="configuration.properties" />
    ```
    
    The `file` attribute points to the new configuration file in YAML format located under `/src/main/resources/config` folder.
    
    Configuration XML for Property Placeholders in Studio 7.
    
    ```xml
    <configuration-properties file="config/configuration.yaml" doc:name="Configuration properties" />
    ```

## [](#migrating-global-http-listener-configuration)Migrating Global HTTP Listener Configuration

Configuration XML for Global HTTP Listener Configuration in Studio 6.

```xml
<http:listener-config name="HTTP_Listener_Configuration" host="${http.host}" port="${http.port}" doc:name="HTTP Listener Configuration"/>
```

The minimal configuration requires specifying `host` and `port` in the inner `http:listener-connection` element. We use the placeholders defined in the previous step.

Configuration XML for Global HTTP Listener Configuration in Studio 7.

```xml
<http:listener-config name="httpListenerConfig">
  <http:listener-connection host="${http.host}" port="${http.port}" />
</http:listener-config>
```

## [](#migrating-mysql-global-configuration)Migrating MySQL Global Configuration

The database connector facilitates setting up _Derby_, _MySQL_ and _Oracle_ databases for use in a Mule app.

1. In the Mule Palette, click `Add Module` and select `Database Connector` among the available modules.
2. Add a `Database Config` Global Configuration Element.
3. In Database Config > Connection, select MySQL Connection.
4. In MySQL JDBC Driver, click Add Dependency and configure the Maven information for the driver.
    
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.6</version>
    </dependency>
5. Complete MySQL Global Configuration with `host`, `port`, `user`, `password` and `database` using previously defined placeholders.
    
    Configuration XML for MySQL Global Configuration in Studio 6.
    
    ```xml
    <db:mysql-config name="MySQL_Configuration" host="${mysql.host}" port="${mysql.port}" user="${mysql.user}" password="${mysql.password}" database="${mysql.database}" doc:name="MySQL Configuration" />
    ```
    
    Configuration XML for MySQL Global Configuration in Studio 7.
    
    ```xml
    <db:config name="MySQL_Configuration" doc:name="Database Config">
      <db:my-sql-connection host="${mysql.host}" port="${mysql.port}" user="${mysql.user}" password="${mysql.password}" database="${mysql.database}" />
    </db:config>
    ```

## [](#migrating-api-autodiscovery-configuration)Migrating API Autodiscovery Configuration

The `api-platform-gw` global element is required for registering an API in Anypoint Platform.

Configuration XML for API Autodiscovery Configuration in Studio 6.

```xml
<api-platform-gw:api apiName="${autodiscovery.api.name}" version="${autodiscovery.api.version}" flowRef="api-main" create="true" doc:name="API Autodiscovery"/>
```

In Mule Runtime 4.x, the `apiName`, `version`, and `create` attributes were removed. Just the `apiId` and `flowRef` attributes are required. `apiId` is generated by API Manager and visible on the API instance dashboard.

For API Autodiscovery Configuration in Mule Runtime 4.x:

1. Add the following Namespace, Schema `global.xml` Configuration file.
    
    xmlns:api-gateway="http://www.mulesoft.org/schema/mule/api-gateway"
    http://www.mulesoft.org/schema/mule/api-gateway http://www.mulesoft.org/schema/mule/api-gateway/current/mule-api-gateway.xsd
2. Add the required Autodiscovery Dependency Information to project `pom.xml` file.
    
    <dependency>
      <groupId>com.mulesoft.anypoint</groupId>
      <artifactId>mule-module-autodiscovery</artifactId>
      <version>4.0.0</version>
    </dependency>
    
    Configuration XML for API Autodiscovery Configuration in Studio 7.
    
    ```xml
    <api-gateway:autodiscovery apiId="${autodiscovery.api.id}" flowRef="api-product-main" doc:name="API Autodiscovery"/>
    ```

## [](#migrating-global-validation-configuration)Migrating Global Validation Configuration

Configuration XML for Global Validation Configuration in Studio 6.

```xml
<validation:config name="Validation_Configuration" doc:name="Validation Configuration"/>
```

Opposite to Mule Runtime 3.x, adding the Validation Module to the Mule Palette is required to proceed with the configuration.

1. In the Mule Palette, click `Add Module` and select `Validation Module` among the available modules.
2. Add a `Validation Config` Global Configuration Element.

Configuration XML for Global Validation Configuration in Studio 7.

```xml
<validation:config name="Validation_Config" doc:name="Validation Config" />
```

## [](#migrating-get-products-flow)Migrating _get-products-flow_

`get-products-flow` returns products from the database filtering by `Product Category` and/or `Product Name` also supporting paginated queries with `offset` and `maxResults` parameters.

![get-products-flow in Studio 6](/mulesoft/current/en-us/mule-runtime/4.4/_images/m3-apikit-based-example-get-products-flow.png)

Figure 1. get-products-flow in Studio 6

Configuration XML for get-products-flow in Studio 6.

```xml
<flow name="get-products-flow">
  <message-properties-transformer doc:name="Get Query Params" scope="invocation">
    <add-message-property key="queryOffset" value="#[Integer.valueOf(message.inboundProperties.'http.query.params'.offset)]" />
    <add-message-property key="queryLimit" value="#[Integer.valueOf(message.inboundProperties.'http.query.params'.maxResults)]" />
    <add-message-property key="queryName" value="#[ (message.inboundProperties.'http.query.params'.name != null) ? ('%'+message.inboundProperties.'http.query.params'.name+'%') : '%%']" />
    <add-message-property key="queryCategory" value="#[ (message.inboundProperties.'http.query.params'.category != null) ? ('%'+message.inboundProperties.'http.query.params'.category+'%') : '%%']" />
  </message-properties-transformer>
  <db:select config-ref="MySQL_Configuration" doc:name="Query Products">
    <db:parameterized-query><![CDATA[SELECT  p.id, p.name, p.description, p.product_number, p.manufactured, p.colors, p.categories, p.stock, p.safety_stock_level, p.standard_cost, p.list_price, p.size, p.size_unit_measure_code, p.weight, p.weight_unit_measure_code, p.days_to_manufacture, p.images,  p.modified_date, p.created_date
FROM product p
WHERE LOWER(p.name) like #[flowVars.queryName.toLowerCase()] AND LOWER(p.categories) like #[flowVars.queryCategory.toLowerCase()]
LIMIT #[flowVars.queryLimit]
OFFSET #[flowVars.queryOffset]]]>
    </db:parameterized-query>
  </db:select>
  <dw:transform-message doc:name="Products to JSON">
    <dw:set-payload resource="classpath:mappings/get-products-response.dwl"/>
  </dw:transform-message>
</flow>
```

1. There are no changes regarding `get-products-flow` definition.
    
    ```xml
    <flow name="get-products-flow">
    ```
2. Create a package with the name `variables` under `src/main/resources` folder.
3. Create the file `set-queryCategory-variable.dwl` under `src/main/resources/variables` folder and write a DW script for setting `queryCategory` flow variable.
    
    %dw 2.0
    output application/java
    var queryCategory = attributes.queryParams.category
    ---
    if (queryCategory != null)
    	queryCategory
    else
    	'%%'
4. Create the file `set-queryLimit-variable.dwl` under `src/main/resources/variables` folder and write a DW script for setting `queryLimit` flow variable.
    
    %dw 2.0
    output application/java
    ---
    attributes.queryParams.maxResults as Number
5. Create the file `set-queryName-variable.dwl` under `src/main/resources/variables` folder and write a DW script for setting `queryName` flow variable.
    
    %dw 2.0
    output application/java
    var queryName = attributes.queryParams.name
    ---
    if (queryName != null)
    	queryName
    else
    	'%%'
6. Create the file `set-queryOffset-variable.dwl` under `src/main/resources/variables` folder and write a DW script for setting `queryOffset` flow variable.
    
    %dw 2.0
    output application/java
    ---
    attributes.queryParams.offset as Number
7. Add a `Transform component` to replace the logic inside `message-properties-transformer` and set the variables `queryOffset`, `queryLimit`, `queryName` and `queryCategory` referencing to its DW script.
    
    ```xml
    <flow name="get-products-flow">
      <ee:transform doc:name="Get Query Params" doc:id="ab756164-e1df-4fc5-8fbe-8f4f8cafc2f6">
        <ee:message />
        <ee:variables>
         <ee:set-variable variableName="queryOffset" resource="variables/set-queryOffset-variable.dwl" />
         <ee:set-variable variableName="queryLimit" resource="variables/set-queryLimit-variable.dwl" />
         <ee:set-variable variableName="queryName" resource="variables/set-queryName-variable.dwl" />
         <ee:set-variable variableName="queryCategory" resource="variables/set-queryCategory-variable.dwl" />
       </ee:variables>
     </ee:transform>
    </flow>
    ```
8. Add a `db:select` element, referencing the MySQL Global Configuration. Use the colon (:) syntax in parametrized queries. Parameters must be supplied as key-value pairs into the `db:input-parameters` element.
    
    ```xml
    <db:select config-ref="MySQL_Configuration" doc:name="Query Products">
      <db:sql >SELECT  p.id, p.name, p.description, p.product_number, p.manufactured, p.colors, p.categories, p.stock, p.safety_stock_level, p.standard_cost, p.list_price, p.size, p.size_unit_measure_code, p.weight, p.weight_unit_measure_code, p.days_to_manufacture, p.images,  p.modified_date, p.created_date
    FROM product p
    WHERE LOWER(p.name) like :name AND LOWER(p.categories) like :category
    LIMIT :limit
    OFFSET :offset</db:sql>
      <db:input-parameters ><![CDATA[#[{'name' : lower(vars.queryName), 'category': lower(vars.queryCategory), 'limit': vars.queryLimit, 'offset': vars.queryOffset}]]]></db:input-parameters>
    </db:select>
    ```
9. Create a package with the name `mappings` under `src/main/resources` folder.
10. Create the file `get-products-response.dwl` under `src/main/resources/mappings` folder.
11. Migrate `get-products-response.dwl` DW 1.0 script to DW 2.0.
    
    Transformation for get-products-response in DW 1.0.
    
    %dw 1.0
    %output application/json
    ---
    payload map {
    	id: $.id,
    	categories: ($.categories default "") splitBy ",",
    	colors: ($.colors default "") splitBy ",",
    	images: ($.images default "") splitBy ",",
    	createdDate: $.created\_date as :string {format: "yyyy-MM-dd"},
    	modifiedDate: $.modified\_date as :string {format: "yyyy-MM-dd"},
    	safetyStockLevel: $.safety\_stock\_level as :number,
    	stock: $.stock as :number,
    	daysToManufacture: $.days\_to\_manufacture,
    	name: $.name,
    	description: $.description,
    	listPrice: $.list\_price,
    	manufactured: $.manufactured,
    	productNumber: $.product\_number,
    	size: $.size,
    	sizeUnitMeasureCode: $.size\_unit\_measure\_code,
    	standardCost: $.standard\_cost,
    	weightUnitMeasureCode: $.weight\_unit\_measure\_code,
    	weight: $.weight
    }
    
    Transformation for get-products-response in DW 2.0.
    
    %dw 2.0
    output application/json
    ---
    payload map {
    	id: $.id,
    	categories: ($.categories default "") splitBy ",",
    	colors: ($.colors default "") splitBy ",",
    	images: ($.images default "") splitBy ",",
    	createdDate: $.created\_date as String {format: "yyyy-MM-dd"},
    	modifiedDate: $.modified\_date as String {format: "yyyy-MM-dd"},
    	safetyStockLevel: $.safety\_stock\_level as Number,
    	stock: $.stock as Number,
    	daysToManufacture: $.days\_to\_manufacture,
    	name: $.name,
    	description: $.description,
    	listPrice: $.list\_price,
    	manufactured: $.manufactured,
    	productNumber: $.product\_number,
    	size: $.size,
    	sizeUnitMeasureCode: $.size\_unit\_measure\_code,
    	standardCost: $.standard\_cost,
    	weightUnitMeasureCode: $.weight\_unit\_measure\_code,
    	weight: $.weight
    }
12. Finally, add a `Transform component` that sets the payload using the DW 2.0 transformation.
    
    ```xml
    <flow name="get-products-flow">
    	<!-- more logic here -->
    	<ee:transform doc:name="Products to JSON">
    		<ee:message>
    			<ee:set-payload resource="mappings/get-products-response.dwl" />
    		</ee:message>
    	</ee:transform>
    </flow>
    ```

Configuration XML for get-products-flow in Studio 7.

```xml
<flow name="get-products-flow">
  <ee:transform doc:name="Get Query Params" doc:id="ab756164-e1df-4fc5-8fbe-8f4f8cafc2f6">
    <ee:message />
    <ee:variables>
      <ee:set-variable variableName="queryOffset" resource="variables/set-queryOffset-variable.dwl" />
      <ee:set-variable variableName="queryLimit" resource="variables/set-queryLimit-variable.dwl" />
      <ee:set-variable variableName="queryName" resource="variables/set-queryName-variable.dwl" />
      <ee:set-variable variableName="queryCategory" resource="variables/set-queryCategory-variable.dwl" />
    </ee:variables>
  </ee:transform>
  <db:select config-ref="MySQL_Configuration" doc:name="Query Products">
    <db:sql>SELECT p.id, p.name, p.description, p.product_number,
				p.manufactured, p.colors, p.categories, p.stock,
				p.safety_stock_level, p.standard_cost, p.list_price, p.size,
				p.size_unit_measure_code, p.weight, p.weight_unit_measure_code,
				p.days_to_manufacture, p.images, p.modified_date, p.created_date
				FROM product p
				WHERE LOWER(p.name) like :name AND LOWER(p.categories) like :category
				LIMIT :limit
				OFFSET :offset</db:sql>
    <db:input-parameters><![CDATA[#[{'name' : lower(vars.queryName), 'category': lower(vars.queryCategory), 'limit': vars.queryLimit, 'offset': vars.queryOffset}]]]></db:input-parameters>
  </db:select>
  <ee:transform doc:name="Products to JSON">
    <ee:message>
      <ee:set-payload resource="mappings/get-products-response.dwl" />
    </ee:message>
  </ee:transform>
</flow>
```

![get-products-flow in Studio 7](/mulesoft/current/en-us/mule-runtime/4.4/_images/m4-apikit-based-example-get-products-flow.png)

Figure 2. get-products-flow in Studio 7

## [](#migrating-get-product-by-id-flow)Migrating _get-product-by-id-flow_

`get-product-by-id-flow` returns a product from the database filtering by `id`. If there isn’t a product with the required id, an `HTTP 404 Not Found` error is returned.

![get-product-by-id-flow in Studio 6](/mulesoft/current/en-us/mule-runtime/4.4/_images/m3-apikit-based-example-get-product-by-id-flow.png)

Figure 3. get-product-by-id-flow in Studio 6

Configuration XML for get-product-by-id-flow in Studio 6.

```xml
<flow name="get-product-by-id-flow">
  <db:select config-ref="MySQL_Configuration" doc:name="Get by Id">
    <db:parameterized-query><![CDATA[SELECT p.id, p.name, p.description, p.product_number, p.manufactured, p.colors, p.categories, p.stock, p.safety_stock_level, p.standard_cost, p.list_price, p.size, p.size_unit_measure_code, p.weight, p.weight_unit_measure_code, p.days_to_manufacture, p.images,  p.modified_date, p.created_date FROM product p where p.id = #[id]]]></db:parameterized-query>
  </db:select>
  <validation:is-true config-ref="Validation_Configuration" doc:name="Is Not Empty" exceptionClass="org.mule.module.apikit.exception.NotFoundException" expression="#[payload.size() &gt; 0]"/>
  <dw:transform-message doc:name="Product to JSON">
    <dw:set-payload resource="classpath:mappings/get-product-by-id-response.dwl"/>
  </dw:transform-message>
</flow>
```

1. There are no changes regarding `get-product-by-id-flow` definition.
    
    ```xml
    <flow name="get-product-by-id-flow" />
    ```
2. Create `set-productId-variable.dwl` under `src/main/resources/variables` folder. Add the following logic for getting the `id` from `uriParams`.
    
    %dw 2.0
    output application/java
    ---
    attributes.uriParams.id
3. Add a `Transform component` that references the DW script that sets a variable with the `productId` value received as a `URI parameter`.
    
    ```xml
    <flow name="get-product-by-id-flow">
      <ee:transform doc:name="Get Uri Params">
        <ee:message />
        <ee:variables>
          <ee:set-variable variableName="id" resource="variables/set-productId-variable.dwl" />
        </ee:variables>
      </ee:transform>
    </flow>
    ```
4. Add a `db:select` element, referencing the MySQL Global Configuration. Use the colon (:) syntax in parametrized queries. Parameters must be supplied as key-value pairs into the `db:input-parameters` element.
    
    ```xml
    <db:select config-ref="MySQL_Configuration" doc:name="Get by Id">
      <db:sql>SELECT p.id, p.name, p.description, p.product_number, p.manufactured, p.colors, p.categories, p.stock, p.safety_stock_level, p.standard_cost, p.list_price, p.size, p.size_unit_measure_code, p.weight, p.weight_unit_measure_code, p.days_to_manufacture, p.images,  p.modified_date, p.created_date
    FROM product p
    where p.id = :id</db:sql>
      <db:input-parameters><![CDATA[#[{'id' : vars.id}]]]></db:input-parameters>
    </db:select>
    ```
5. Add a `validation:is-true` element after the `db:select` that checks if the query has returned results. If not, throw an `APP:NOT_FOUND` error. Notice that as `MEL` has been replaced by `DataWeave` as the default expression language, `[payload.size() > 0]` is rewritten as `[sizeOf(payload) > 0]`.
    
    ```xml
    <validation:is-true doc:name="Is Not Empty" config-ref="Validation_Config" expression="#[sizeOf(payload) &gt; 0]">
      <error-mapping sourceType="VALIDATION:INVALID_BOOLEAN" targetType="APP:NOT_FOUND" />
    </validation:is-true>
    ```
6. Create `get-product-by-id-response.dwl` file under `src/main/resources/mappings` folder and migrate DataWeave script for building JSON response from 1.0 to 2.0.
    
    Transformation for get-product-by-id-response in DW 1.0.
    
    %dw 1.0
    %output application/json
    %var product = payload\[0\]
    ---
    {
    	id: product.id,
    	name: product.name,
    	description: product.description,
    	manufactured: product.manufactured,
    	productNumber: product.product\_number,
    	colors: (product.colors default "") splitBy "," ,
    	categories:(product.categories default "") splitBy "," ,
    	safetyStockLevel: product.safety\_socket\_level,
    	standardCost: (product.standard\_cost default "0.0") as :string {format: "##.##"} as :number,
    	listPrice: (product.list\_price default "0.0") as :string {format: "##.##"} as :number,
    	stock: product.stock,
    	safetyStockLevel: product.safety\_stock\_level,
    	daysToManufacture: product.days\_to\_manufacture,
    	size: product.size,
    	sizeUnitMeasureCode: product.size\_unit\_measure\_code,
    	weight: product.weight,
    	weightUnitMeasureCode: product.weight\_unit\_measure\_code,
    	daysToManufacture: product.days\_to\_manufacture,
    	images: (product.images splitBy "," default null),
    	modifiedDate: (product.modified\_date default "") as :date {format: "yyyy-MM-dd"},
    	createdDate: (product.created\_date default "") as :date {format: "yyyy-MM-dd"}
    
    }
    
    Transformation for get-product-by-id-response.dwl in DW 2.0.
    
    %dw 2.0
    output application/json
    var product = payload\[0\]
    ---
    {
    	id: product.id,
    	name: product.name,
    	description: product.description,
    	manufactured: product.manufactured,
    	productNumber: product.product\_number,
    	colors: (product.colors default "") splitBy "," ,
    	categories:(product.categories default "") splitBy "," ,
    	safetyStockLevel: product.safety\_socket\_level,
    	standardCost: (product.standard\_cost default "0.0") as String {format: "##.##"} as Number,
    	listPrice: (product.list\_price default "0.0") as String {format: "##.##"} as Number,
    	stock: product.stock,
    	safetyStockLevel: product.safety\_stock\_level,
    	daysToManufacture: product.days\_to\_manufacture,
    	size: product.size,
    	sizeUnitMeasureCode: product.size\_unit\_measure\_code,
    	weight: product.weight,
    	weightUnitMeasureCode: product.weight\_unit\_measure\_code,
    	daysToManufacture: product.days\_to\_manufacture,
    	images: (product.images splitBy "," default null),
    	modifiedDate: (product.modified\_date default "") as Date {format: "yyyy-MM-dd"},
    	createdDate: (product.created\_date default "") as Date {format: "yyyy-MM-dd"}
    }
7. Finally, add a `Transform component` that sets the payload using the DW 2.0 transformation.
    
    ```xml
    <ee:transform doc:name="Product to JSON">
      <ee:message>
        <ee:set-payload resource="mappings/get-product-by-id-response.dwl" />
      </ee:message>
    </ee:transform>
    ```

Configuration XML for get-product-by-id-flow in Studio 7.

```xml
<flow name="get-product-by-id-flow">
  <ee:transform doc:name="Get Uri Params">
    <ee:message />
    <ee:variables>
      <ee:set-variable variableName="id" resource="variables/set-productId-variable.dwl" />
    </ee:variables>
  </ee:transform>
  <db:select config-ref="MySQL_Configuration" doc:name="Get by Id">
    <db:sql>SELECT p.id, p.name, p.description, p.product_number, p.manufactured, p.colors, p.categories, p.stock, p.safety_stock_level, p.standard_cost, p.list_price, p.size, p.size_unit_measure_code, p.weight, p.weight_unit_measure_code, p.days_to_manufacture, p.images,  p.modified_date, p.created_date
FROM product p
where p.id = :id</db:sql>
    <db:input-parameters><![CDATA[#[{'id' : vars.id}]]]></db:input-parameters>
  </db:select>
  <validation:is-true doc:name="Is Not Empty" config-ref="Validation_Config" expression="#[sizeOf(payload) &gt; 0]">
    <error-mapping sourceType="VALIDATION:INVALID_BOOLEAN" targetType="APP:NOT_FOUND" />
  </validation:is-true>
  <ee:transform doc:name="Product to JSON">
    <ee:message>
      <ee:set-payload resource="mappings/get-product-by-id-response.dwl" />
    </ee:message>
  </ee:transform>
</flow>
```

![get-product-by-id-flow in Studio 7](/mulesoft/current/en-us/mule-runtime/4.4/_images/m4-apikit-based-example-get-product-by-id-flow.png)

Figure 4. get-product-by-id-flow in Studio 7

## [](#migrating-post-product-flow)Migrating _post-product-flow_

`post-product-flow` inserts a product in the database.

![post-product-flow in Studio 6](/mulesoft/current/en-us/mule-runtime/4.4/_images/m3-apikit-based-example-post-product-flow.png)

Figure 5. post-product-flow in Studio 6

Configuration XML for post-product-flow in Studio 6.

```xml
<flow name="post-product-flow">
  <set-variable variableName="originalPayload" value="#[payload:java.lang.String]" doc:name="Set Original Payload" />
  <dw:transform-message doc:name="Json to Map">
    <dw:set-payload resource="classpath:mappings/json-product-to-java.dwl"/>
  </dw:transform-message>
  <transactional action="ALWAYS_BEGIN" doc:name="Transactional">
    <db:insert config-ref="MySQL_Configuration" doc:name="Insert Product" autoGeneratedKeys="true" autoGeneratedKeysColumnNames="id" target="#[payload]">
      <db:parameterized-query><![CDATA[insert into product(name, description, product_number, manufactured, colors, categories, stock, safety_stock_level, standard_cost, list_price, size, size_unit_measure_code, weight, weight_unit_measure_code, days_to_manufacture, images, modified_date, created_date) values(#[payload.name],#[payload.description], #[payload.productNumber], #[payload.manufactured], #[payload.colors],  #[payload.categories], #[payload.stock], #[payload.safetyStockLevel], #[payload.standardCost], #[payload.listPrice], #[payload.size], #[payload.sizeUnitMeasureCode], #[payload.weight], #[payload.weightUnitMeasureCode], #[payload.daysToManufacture], #[payload.images], CURDATE(), CURDATE() );]]></db:parameterized-query>
    </db:insert>
  </transactional>
  <dw:transform-message doc:name="Database to Json">
    <dw:input-variable doc:sample="json.json" mimeType="application/json" variableName="originalPayload" />
    <dw:set-payload resource="classpath:mappings/post-product-response.dwl"/>
  </dw:transform-message>
</flow>
```

1. There are no changes regarding `post-product-flow` definition.
    
    ```xml
    <flow name="post-product-flow" />
    ```
2. Create a `json-to-java.dwl` file into `src/main/resources/mappings` folder to transform the JSON request into a JAVA map.
    
    %dw 2.0
    output application/java
    ---
    payload
3. Create a `json-product-to-java.dwl` file into `src/main/resources/mappings` and migrate the original script from DW 1.0 to 2.0.
    
    Transformation for json-product-to-java.dwl in DW 1.0.
    
    %dw 1.0
    %output application/java
    ---
    {
    	categories: payload.categories joinBy ",",
    	colors: payload.colors joinBy ",",
    	daysToManufacture: payload.daysToManufacture,
    	description: payload.description,
    	images: payload.images joinBy ",",
    	listPrice: payload.listPrice,
    	(manufactured: 1) when payload.manufactured == true,
    	(manufactured: 0) when payload.manufactured == false,
    	name: payload.name,
    	productNumber: payload.productNumber,
    	safetyStockLevel: payload.safetyStockLevel,
    	size: payload.size,
    	sizeUnitMeasureCode: payload.sizeUnitMeasureCode,
    	standardCost: payload.standardCost,
    	stock: payload.stock,
    	weight: payload.weight,
    	weightUnitMeasureCode: payload.weightUnitMeasureCode
    }
    
    Transformation for json-product-to-java.dwl in DW 2.0.
    
    %dw 2.0
    output application/java
    fun getManufacturedCode(value) =
    	if (value == true) 1
    	else 0
    ---
    {
    	categories: payload.categories joinBy ",",
    	colors: payload.colors joinBy ",",
    	daysToManufacture: payload.daysToManufacture,
    	description: payload.description,
    	images: payload.images joinBy ",",
    	listPrice: payload.listPrice,
    	manufactured: getManufacturedCode(payload.manufactured),
    	name: payload.name,
    	productNumber: payload.productNumber,
    	safetyStockLevel: payload.safetyStockLevel,
    	size: payload.size,
    	sizeUnitMeasureCode: payload.sizeUnitMeasureCode,
    	standardCost: payload.standardCost,
    	stock: payload.stock,
    	weight: payload.weight,
    	weightUnitMeasureCode: payload.weightUnitMeasureCode
    }
4. Add a `Transform component` that sets `originalPayload` and `newPayload` using the previously created DataWeave transformations.
    
    ```xml
    <flow name="post-product-flow">
      <ee:transform doc:name="Json to Map">
        <ee:message />
        <ee:variables>
          <ee:set-variable variableName="originalPayload" resource="mappings/json-to-java.dwl" />
          <ee:set-variable variableName="newPayload" resource="mappings/json-product-to-java.dwl" />
        </ee:variables>
      </ee:transform>
    </flow>
    ```
5. For configuring the details of the transaction, replace the Mule 3.x `transactional` scope with the new `try` scope and set the `transactionalAction` attribute to `ALWAYS_BEGIN`.
    
    ```xml
    <try doc:name="Try" transactionalAction="ALWAYS_BEGIN">
    </try>
    ```
6. Add a `db:insert` element into the `Try scope`, referencing the MySQL Global Configuration. Parameters must be supplied as key-value pairs into the `db:input-parameters` element. Notice also the inclusion of `db:auto-generated-keys-column-name` tag for setting the payload with the `ID` that was auto-generated by the Database engine.
    
    ```xml
    <try transactionalAction="ALWAYS_BEGIN" doc:name="Try">
      <db:insert config-ref="MySQL_Configuration" doc:name="Insert Product" autoGenerateKeys="true">
        <db:sql>insert into product(name, description, product_number,
    					manufactured, colors, categories, stock, safety_stock_level,
    					standard_cost, list_price, size, size_unit_measure_code, weight,
    					weight_unit_measure_code, days_to_manufacture, images,
    					modified_date, created_date)
    					values(:name, :description,
    					:product_number, :manufactured, :colors,
    					:categories, :stock,
    					:safety_stock_level, :standard_cost,
    					:list_price, :size,
    					:size_unit_measure_code, :weight,
    					:weight_unit_measure_code,
    					:days_to_manufacture, :images,
    					CURDATE(), CURDATE());
    				</db:sql>
        <db:input-parameters><![CDATA[#[{'name': vars.newPayload.name, 'description': vars.newPayload.description, 'product_number': vars.newPayload.productNumber, 'manufactured': vars.newPayload.manufactured, 'colors': vars.newPayload.colors, 'categories': vars.newPayload.categories, 'stock': vars.newPayload.stock, 'safety_stock_level': vars.newPayload.safetyStockLevel, 'standard_cost': vars.newPayload.standardCost, 'list_price': vars.newPayload.listPrice, 'size': vars.newPayload.size, 'size_unit_measure_code': vars.newPayload.sizeUnitMeasureCode, 'weight': vars.newPayload.weight, 'weight_unit_measure_code': vars.newPayload.weightUnitMeasureCode, 'days_to_manufacture': vars.newPayload.daysToManufacture, 'images': vars.newPayload.images}]]]></db:input-parameters>
        <db:auto-generated-keys-column-names>
          <db:auto-generated-keys-column-name value="id" />
        </db:auto-generated-keys-column-names>
      </db:insert>
    </try>
    ```
7. Create a `post-product-response.dwl` file under `src/main/resources/mappings` and migrate the response transformation from DataWeave 1.0 to 2.0. Notice the difference getting the generated `id` from the payload with the expression `payload.generatedKeys.GENERATED_KEY`.
    
    Transformation for post-product-response.dwl in DW 1.0.
    
    %dw 1.0
    %output application/json
    ---
    flowVars.originalPayload ++
    id: payload\[0\].GENERATED\_KEY
    
    Transformation for post-product-response.dwl in DW 2.0.
    
    %dw 2.0
    output application/json
    ---
    vars.originalPayload ++
    id: payload.generatedKeys.GENERATED\_KEY
8. Add a `Transform component` and set the payload with the DataWeave script.
    
    ```xml
    <ee:transform doc:name="Database to Json">
      <ee:message>
        <ee:set-payload resource="mappings/post-product-response.dwl" />
      </ee:message>
    </ee:transform>
    ```

Configuration XML for post-product-flow in Studio 7.

```xml
<flow name="post-product-flow">
  <ee:transform doc:name="Json to Map">
    <ee:message />
    <ee:variables>
      <ee:set-variable variableName="originalPayload" resource="mappings/json-to-java.dwl" />
      <ee:set-variable variableName="newPayload" resource="mappings/json-product-to-java.dwl" />
    </ee:variables>
  </ee:transform>
  <try transactionalAction="ALWAYS_BEGIN" doc:name="Try">
    <db:insert config-ref="MySQL_Configuration" doc:name="Insert Product" autoGenerateKeys="true">
      <db:sql>insert into product(name, description, product_number,
					manufactured, colors, categories, stock, safety_stock_level,
					standard_cost, list_price, size, size_unit_measure_code, weight,
					weight_unit_measure_code, days_to_manufacture, images,
					modified_date, created_date)
					values(:name, :description,
					:product_number, :manufactured, :colors,
					:categories, :stock,
					:safety_stock_level, :standard_cost,
					:list_price, :size,
					:size_unit_measure_code, :weight,
					:weight_unit_measure_code,
					:days_to_manufacture, :images,
					CURDATE(), CURDATE());
				</db:sql>
      <db:input-parameters><![CDATA[#[{'name': vars.newPayload.name, 'description': vars.newPayload.description, 'product_number': vars.newPayload.productNumber, 'manufactured': vars.newPayload.manufactured, 'colors': vars.newPayload.colors, 'categories': vars.newPayload.categories, 'stock': vars.newPayload.stock, 'safety_stock_level': vars.newPayload.safetyStockLevel, 'standard_cost': vars.newPayload.standardCost, 'list_price': vars.newPayload.listPrice, 'size': vars.newPayload.size, 'size_unit_measure_code': vars.newPayload.sizeUnitMeasureCode, 'weight': vars.newPayload.weight, 'weight_unit_measure_code': vars.newPayload.weightUnitMeasureCode, 'days_to_manufacture': vars.newPayload.daysToManufacture, 'images': vars.newPayload.images}]]]></db:input-parameters>
      <db:auto-generated-keys-column-names>
        <db:auto-generated-keys-column-name value="id" />
      </db:auto-generated-keys-column-names>
    </db:insert>
  </try>
  <ee:transform doc:name="Database to Json">
    <ee:message>
      <ee:set-payload resource="mappings/post-product-response.dwl" />
    </ee:message>
  </ee:transform>
</flow>
```

![post-product-flow in Studio 7](/mulesoft/current/en-us/mule-runtime/4.4/_images/m4-apikit-based-example-post-product-flow.png)

Figure 6. post-product-flow in Studio 7

## [](#migrating-put-product-flow)Migrating _put-product-flow_

`put-product-flow` updates a product in the database based on the specified `id`.

![put-product-flow in Studio 6](/mulesoft/current/en-us/mule-runtime/4.4/_images/m3-apikit-based-example-put-product-flow.png)

Figure 7. put-product-flow in Studio 6

Configuration XML for put-product-flow in Studio 6.

```xml
<flow name="put-product-flow">
  <dw:transform-message doc:name="JSon to Product">
    <dw:set-payload resource="classpath:mappings/put-json-product-to-java.dwl"/>
  </dw:transform-message>
  <transactional action="ALWAYS_BEGIN" doc:name="Transactional">
    <db:update config-ref="MySQL_Configuration" doc:name="Update Product">
      <db:parameterized-query><![CDATA[update product set name = #[payload.name], description = #[payload.description], product_number = #[payload.productNumber], manufactured = #[payload.manufactured], colors = #[payload.colors], categories= #[payload.categories], stock = #[payload.stock], safety_stock_level = #[payload.safetyStockLevel], standard_cost = #[payload.standardCost], list_price = #[payload.listPrice], size = #[payload.size], size_unit_measure_code = #[payload.sizeUnitMeasureCode], weight = #[payload.weight], weight_unit_measure_code = #[payload.weightUnitMeasureCode], days_to_manufacture = #[payload.daysToManufacture], images = #[payload.images],  modified_date = CURDATE() where id = #[id]]]></db:parameterized-query>
    </db:update>
  </transactional>
  <set-payload value="#[NullPayload.getInstance()]" doc:name="Set Payload" />
  <set-property propertyName="http.status" value="204" doc:name="Set Status" />
</flow>
```

1. There are no changes regarding `put-product-flow` definition.
    
    ```xml
    <flow name="put-product-flow" />
    ```
2. Create a `put-json-product-to-java.dwl` file under `src/main/resources/mappings` folder and migrate the original script from DW 1.0 to 2.0.
    
    Transformation for put-json-product-to-java.dwl in DW 1.0.
    
    %dw 1.0
    %output application/java
    ---
    {
    	categories: payload.categories joinBy ",",
    	colors: payload.colors joinBy ",",
    	daysToManufacture: payload.daysToManufacture,
    	description: payload.description,
    	images: payload.images joinBy ",",
    	listPrice: payload.listPrice,
    	manufactured: payload.manufactured,
    	name: payload.name,
    	productNumber: payload.productNumber,
    	safetyStockLevel: payload.safetyStockLevel,
    	size: payload.size,
    	sizeUnitMeasureCode: payload.sizeUnitMeasureCode,
    	standardCost: payload.standardCost,
    	stock: payload.stock,
    	weight: payload.weight,
    	weightUnitMeasureCode: payload.weightUnitMeasureCode
    }
    
    Transformation for put-json-product-to-java.dwl in DW 2.0.
    
    %dw 2.0
    output application/java
    ---
    {
    	categories: payload.categories joinBy ",",
    	colors: payload.colors joinBy ",",
    	daysToManufacture: payload.daysToManufacture,
    	description: payload.description,
    	images: payload.images joinBy ",",
    	listPrice: payload.listPrice,
    	manufactured: payload.manufactured,
    	name: payload.name,
    	productNumber: payload.productNumber,
    	safetyStockLevel: payload.safetyStockLevel,
    	size: payload.size,
    	sizeUnitMeasureCode: payload.sizeUnitMeasureCode,
    	standardCost: payload.standardCost,
    	stock: payload.stock,
    	weight: payload.weight,
    	weightUnitMeasureCode: payload.weightUnitMeasureCode
    }
3. Add a `Transform component` that sets `updatePayload` using the previously created DataWeave transformation and `id` with `variables/set-productId-variable.dwl` script.
    
    ```xml
    <flow name="put-product-flow">
      <ee:transform doc:name="JSon to Product">
        <ee:message />
        <ee:variables >
          <ee:set-variable variableName="updatePayload" resource="mappings/put-json-product-to-java.dwl" />
          <ee:set-variable variableName="id" resource="variables/set-productId-variable.dwl" />
        </ee:variables>
      </ee:transform>
    </flow>
    ```
4. For configuring the details of the transaction, replace the Mule 3.x `transactional` scope with the new `try` scope and set the `transactionalAction` attribute to `ALWAYS_BEGIN`.
    
    ```xml
    <try doc:name="Try" transactionalAction="ALWAYS_BEGIN">
    </try>
    ```
5. Add a `db:update` element into the `Try scope`, referencing the MySQL Global Configuration. Parameters must be supplied as key-value pairs into the `db:input-parameters` element.
    
    ```xml
    <try doc:name="Try" transactionalAction="ALWAYS_BEGIN">
      <db:update config-ref="MySQL_Configuration" doc:name="Update Product">
        <db:sql >update product
    set name = :name, description = :description, product_number = :product_number, manufactured = :manufactured, colors = :colors, categories= :categories, stock = :stock, safety_stock_level = :safety_stock_level, standard_cost = :standard_cost, list_price = :list_price, size = :size, size_unit_measure_code = :size_unit_measure_code, weight = :weight, weight_unit_measure_code = :weight_unit_measure_code, days_to_manufacture = :days_to_manufacture, images = :images,  modified_date = CURDATE()
    where id = :id</db:sql>
        <db:input-parameters ><![CDATA[#[{'name': vars.updatePayload.name, 'description': vars.updatePayload.description, 'product_number': vars.updatePayload.productNumber, 'manufactured': vars.updatePayload.manufactured, 'colors': vars.updatePayload.colors, 'categories': vars.updatePayload.categories, 'stock': vars.updatePayload.stock, 'safety_stock_level': vars.updatePayload.safetyStockLevel, 'standard_cost': vars.updatePayload.standardCost, 'list_price': vars.updatePayload.listPrice, 'size': vars.updatePayload.size, 'size_unit_measure_code': vars.updatePayload.sizeUnitMeasureCode, 'weight': vars.updatePayload.weight, 'weight_unit_measure_code': vars.updatePayload.weightUnitMeasureCode, 'days_to_manufacture': vars.updatePayload.daysToManufacture, 'images': vars.updatePayload.images, 'id': vars.id}]]]></db:input-parameters>
      </db:update>
    </try>
    ```
6. Add a `Transform component` and set the `httpStatus` variable with `204` using `set-httpStatus-with-204.dwl` file into `src/main/resources/variables`.
    
    ```xml
    <ee:transform doc:name="Set Status">
      <ee:message />
      <ee:variables >
        <ee:set-variable variableName="httpStatus" resource="variables/set-httpStatus-with-204.dwl" />
      </ee:variables>
    </ee:transform>
    ```

Configuration XML for put-product-flow in Studio 7.

```xml
<flow name="put-product-flow">
  <ee:transform doc:name="JSon to Product">
    <ee:message />
    <ee:variables >
      <ee:set-variable variableName="updatePayload" resource="mappings/put-json-product-to-java.dwl" />
      <ee:set-variable variableName="id" resource="variables/set-productId-variable.dwl" />
    </ee:variables>
  </ee:transform>
  <try doc:name="Try" transactionalAction="ALWAYS_BEGIN">
    <db:update config-ref="MySQL_Configuration" doc:name="Update Product">
      <db:sql >update product
set name = :name, description = :description, product_number = :product_number, manufactured = :manufactured, colors = :colors, categories= :categories, stock = :stock, safety_stock_level = :safety_stock_level, standard_cost = :standard_cost, list_price = :list_price, size = :size, size_unit_measure_code = :size_unit_measure_code, weight = :weight, weight_unit_measure_code = :weight_unit_measure_code, days_to_manufacture = :days_to_manufacture, images = :images,  modified_date = CURDATE()
where id = :id</db:sql>
      <db:input-parameters ><![CDATA[#[{'name': vars.updatePayload.name, 'description': vars.updatePayload.description, 'product_number': vars.updatePayload.productNumber, 'manufactured': vars.updatePayload.manufactured, 'colors': vars.updatePayload.colors, 'categories': vars.updatePayload.categories, 'stock': vars.updatePayload.stock, 'safety_stock_level': vars.updatePayload.safetyStockLevel, 'standard_cost': vars.updatePayload.standardCost, 'list_price': vars.updatePayload.listPrice, 'size': vars.updatePayload.size, 'size_unit_measure_code': vars.updatePayload.sizeUnitMeasureCode, 'weight': vars.updatePayload.weight, 'weight_unit_measure_code': vars.updatePayload.weightUnitMeasureCode, 'days_to_manufacture': vars.updatePayload.daysToManufacture, 'images': vars.updatePayload.images, 'id': vars.id}]]]></db:input-parameters>
    </db:update>
  </try>
  <ee:transform doc:name="Set Status">
    <ee:message />
    <ee:variables >
      <ee:set-variable variableName="httpStatus" resource="variables/set-httpStatus-with-204.dwl" />
    </ee:variables>
  </ee:transform>
</flow>
```

![put-product-flow in Studio 7](/mulesoft/current/en-us/mule-runtime/4.4/_images/m4-apikit-based-example-put-product-flow.png)

Figure 8. put-product-flow in Studio 7

## [](#migrating-delete-product-flow)Migrating _delete-product-flow_

`delete-product-flow` deletes the product record from the MySQL database with the `id` specified as a `URI parameter` returning an HTTP 204 status code.

![delete-product-flow in Studio 6](/mulesoft/current/en-us/mule-runtime/4.4/_images/m3-apikit-based-example-delete-product-flow.png)

Figure 9. delete-product-flow in Studio 6

Configuration XML for delete-product-flow in Studio 6.

```xml
<flow name="delete-product-flow">
  <transactional action="ALWAYS_BEGIN" doc:name="Transactional">
    <db:delete config-ref="MySQL_Configuration" doc:name="Delete Product">
      <db:parameterized-query><![CDATA[delete from product where id=#[id]]]></db:parameterized-query>
    </db:delete>
  </transactional>
  <set-payload value="#[NullPayload.getInstance()]" doc:name="Set Payload"/>
  <set-property propertyName="http.status" value="204" doc:name="Set Status"/>
</flow>
```

1. There are no changes regarding `delete-product-flow` definition.
    
    ```xml
    <flow name="delete-product-flow" />
    ```
2. Add a `Transform component` that references the DW script that sets a variable with the `productId` value received as a `URI parameter`.
    
    ```xml
    <flow name="delete-product-flow">
      <ee:transform doc:name="Set productId variable">
        <ee:message />
        <ee:variables>
          <ee:set-variable variableName="productId" resource="variables/set-productId-variable.dwl" />
        </ee:variables>
      </ee:transform>
    </flow>
    ```
3. For configuring the details of the transaction, replace the Mule 3.x `transactional` scope with the new `try` scope and set the `transactionalAction` attribute to `ALWAYS_BEGIN`.
    
    ```xml
    <try doc:name="Try" transactionalAction="ALWAYS_BEGIN">
    </try>
    ```
4. Add a `db:delete` element into the `Try scope`, referencing the MySQL Global Configuration. Parameters must be supplied as key-value pairs into the `db:input-parameters` element. Opposite to Mule 3.x, the previously defined `productId` flow variable must be accessed as `vars.productId` instead of `flowVars.productId`.
    
    ```xml
    <try doc:name="Try" transactionalAction="ALWAYS_BEGIN">
      <db:delete config-ref="MySQL_Configuration" doc:name="Delete Product">
        <db:sql>delete from product where id=:productId</db:sql>
        <db:input-parameters><![CDATA[#[{'productId' : vars.productId}]]]></db:input-parameters>
      </db:delete>
    </try>
    ```
5. Create a `set-httpStatus-with-204.dwl` file under `src/main/resources/variables` as follows.
    
    %dw 2.0
    output application/java
    ---
    204
6. Set `httpStatus` variable with the value `204` using a `Transform Component` for defining a `NO CONTENT` response code.
    
    ```xml
    <ee:transform doc:name="Set 204 HTTP Status code">
      <ee:message />
      <ee:variables>
        <ee:set-variable variableName="httpStatus" resource="variables/set-httpStatus-with-204.dwl" />
      </ee:variables>
    </ee:transform>
    ```

To return a specific HTTP Status code, instead of setting a `http.status` property, APIkit in Mule 4 requires setting a variable with the name `httpStatus`.

Configuration XML for delete-product-flow in Studio 7.

```xml
<flow name="delete-product-flow">
  <ee:transform doc:name="Set productId variable">
    <ee:message />
    <ee:variables>
      <ee:set-variable variableName="productId" resource="variables/set-productId-variable.dwl" />
    </ee:variables>
  </ee:transform>
  <try doc:name="Try" transactionalAction="ALWAYS_BEGIN">
    <db:delete config-ref="MySQL_Configuration" doc:name="Delete Product">
      <db:sql>delete from product where id=:productId</db:sql>
      <db:input-parameters><![CDATA[#[{'productId' : vars.productId}]]]></db:input-parameters>
    </db:delete>
  </try>
  <ee:transform doc:name="Set 204 HTTP Status code">
    <ee:message />
    <ee:variables>
      <ee:set-variable variableName="httpStatus" resource="variables/set-httpStatus-with-204.dwl" />
    </ee:variables>
  </ee:transform>
</flow>
```

![delete-product-flow in Studio 7](/mulesoft/current/en-us/mule-runtime/4.4/_images/m4-apikit-based-example-delete-product-flow.png)

Figure 10. delete-product-flow in Studio 7

## [](#migrating-backend-flows)Migrating Backend Flows

To migrate backend flows:

For each Backend Flow generated by APIkit, add a `flow-ref` to its implementation.

\+ .Configuration XML for Backend Flows in Studio 6.

```xml
<flow name="get:/product:api-config">
  <flow-ref name="get-products-flow" doc:name="get-products-flow" />
</flow>
<flow name="get:/product/{id}:api-config">
  <flow-ref name="get-product-by-id-flow" doc:name="get-product-by-id-flow" />
</flow>
<flow name="post:/product:application/json:api-config">
  <flow-ref name="post-product-flow" doc:name="post-product-flow" />
</flow>
<flow name="delete:/product/{id}:api-config">
  <flow-ref name="delete-product-flow" doc:name="delete-product-flow" />
</flow>
<flow name="put:/product/{id}:application/json:api-config">
  <flow-ref name="put-product-flow" doc:name="put-product-flow" />
</flow>
```

+

\+ .Configuration XML for Backend Flows in Studio 7.

```xml
<flow name="get:\product:api-product-config">
  <flow-ref name="get-products-flow" doc:name="get-products-flow" />
</flow>
<flow name="get:\product\(id):api-product-config">
  <flow-ref doc:name="get-product-by-id-flow" name="get-product-by-id-flow"/>
</flow>
<flow name="post:\product:application\json:api-product-config">
  <flow-ref name="post-product-flow" doc:name="post-product-flow" />
</flow>
<flow name="delete:\product\(id):application\json:api-product-config">
  <flow-ref doc:name="delete-product-flow" doc:id="38894873-9a01-4e59-8362-5eefce5ea043" name="delete-product-flow"/>
</flow>
<flow name="put:\product\(id):application\json:api-product-config">
  <flow-ref doc:name="put-product-flow" doc:id="e64cf378-26a2-4435-8d0d-269c50282b3c" name="put-product-flow"/>
</flow>
```

## [](#extending-default-apikit-global-exception-strategies)Extending default APIkit Global Exception Strategies

1. Add `APP:NOT_FOUND` exception type to the ApiKit-generated 404 mapping to handle the exception thrown by the `validation:is-true` element in `get-product-by-id-flow`. You can repeat this process for any other errors you want to map to a specific status code.
    
    Configuration XML for ApiKit Mapping 404 in Studio 6.
    
    ```xml
    <apikit:mapping statusCode="404">
      <apikit:exception value="org.mule.module.apikit.exception.NotFoundException" />
      <set-property propertyName="Content-Type" value="application/json" doc:name="Property" />
      <set-payload value="{ &quot;message&quot;: &quot;Resource not found&quot; }" doc:name="Set Payload" />
    </apikit:mapping>
    ```
    
    Configuration XML for ApiKit Mapping 404 in Studio 7.
    
    ```xml
    <on-error-propagate type="APIKIT:NOT_FOUND, APP:NOT_FOUND" doc:name="On Error Propagate" enableNotifications="true" logException="true">
      <ee:transform xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd" doc:id="70f893cb-6106-42d9-9a95-e201e9349159">
        <ee:message>
          <ee:set-payload><![CDATA[%dw 2.0
    output application/json
    ---
    {message: "Resource not found"}]]></ee:set-payload>
        </ee:message>
        <ee:variables>
          <ee:set-variable variableName="httpStatus"><![CDATA[404]]></ee:set-variable>
        </ee:variables>
      </ee:transform>
    </on-error-propagate>
    ```
2. Add a Generic ApiKit Mapping 500 for all the non previously managed exceptions.
    
    Configuration XML for Generic ApiKit Mapping 500 in Studio 6.
    
    ```xml
    <apikit:mapping-exception-strategy name="api-apiKitGlobalExceptionMapping">
      <!-- other exception strategies here -->
      <apikit:mapping statusCode="500">
        <apikit:exception value="java.lang.Exception" />
        <set-property propertyName="Content-Type" value="application/json" doc:name="Property" />
        <set-payload value="{ &quot;message&quot;: &quot;Internal Server Error&quot; }" doc:name="Set Payload" />
      </apikit:mapping>
    </apikit:mapping-exception-strategy>
    ```
    
    Configuration XML for Generic ApiKit Mapping 500 in Studio 7.
    
    ```xml
    <error-handler>
      <!-- other exception strategies here -->
      <on-error-propagate doc:name="On Error Propagate" enableNotifications="true" logException="true">
        <ee:transform xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd" doc:id="7e8049ff-cae6-4937-8569-c36bb7f06dad">
          <ee:message>
            <ee:set-payload><![CDATA[%dw 2.0
    output application/json
    ---
    {message: "Internal Server Error"}]]></ee:set-payload>
          </ee:message>
          <ee:variables>
            <ee:set-variable variableName="httpStatus"><![CDATA[500]]></ee:set-variable>
          </ee:variables>
        </ee:transform>
      </on-error-propagate>
    </error-handler>
    ```