Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

MuleSoft: Contract-First Web Service Development

DZone's Guide to

MuleSoft: Contract-First Web Service Development

Learn the quick and easy steps on how to develop and expose a WSDL-first and contract-first web service by using Anypoint studio.

· Integration Zone ·
Free Resource

The State of API Integration 2018: Get Cloud Elements’ report for the most comprehensive breakdown of the API integration industry’s past, present, and future.

Learn about how to develop a WSDL-first web service using Anypoint studio.

In short, the steps required to expose a contract-first web service are:

  1. Define contract (WSDL and XML schema files).
  2. Create Mule project in Anypoint studio and place the contract files.
  3. Create a flow with an HTTP endpoint.
  4. Configure a CXF component.
  5. Implement Service Endpoint Interface (SEI) and configure the implementation as a Java component.
  6. Test the component using SOAP UI.

1. Define Contract (WSDL and XML Schema Files)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions
	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
	xmlns:mov="http://ss.com/ws/MovieService/"
	xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="MovieService"
targetNamespace="http://ss.com/ws/MovieService/">
	<wsdl:types>
		<xsd:schema targetNamespace="http://ss.com/ws/MovieService/" attributeFormDefault="unqualified" elementFormDefault="qualified">
			<xsd:element name="movieSearch" type="mov:movieSearchRequestType" />
			<xsd:element name="movieSearchResponse" type="mov:movieSearchResponseType"/>
			<xsd:complexType name="movieSearchRequestType">
				<xsd:sequence>
					<xsd:element name="location" type="xsd:string" />
					<xsd:element name="date" type="xsd:date" />
					<xsd:element name="movieName" type="xsd:string" />
				</xsd:sequence>
			</xsd:complexType>
			<xsd:complexType name="movieSearchResponseType">
				<xsd:sequence>
					<xsd:element name="showDetails" type="mov:showType" minOccurs="0" maxOccurs="unbounded"/>
				</xsd:sequence>
			</xsd:complexType>
			<xsd:complexType name="showType">
				<xsd:sequence>
					<xsd:element name="cinemaName" type="xsd:string" />
					<xsd:element name="showTimes" type="xsd:string" minOccurs="1" maxOccurs="unbounded"/>
				</xsd:sequence>
			</xsd:complexType>
		</xsd:schema>
	</wsdl:types>
	<wsdl:message name="movieSearchRequest">
		<wsdl:part element="mov:movieSearch" name="parameters" />
	</wsdl:message>
	<wsdl:message name="movieSearchResponse">
		<wsdl:part element="mov:movieSearchResponse" name="parameters" />
	</wsdl:message>
	<wsdl:portType name="MovieService">
		<wsdl:operation name="movieSearch">
			<wsdl:input message="mov:movieSearchRequest" />
			<wsdl:output message="mov:movieSearchResponse" />
		</wsdl:operation>
	</wsdl:portType>
	<wsdl:binding name="MovieServiceSOAP" type="mov:MovieService">
		<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
		<wsdl:operation name="movieSearch">
			<soap:operation soapAction="http://ss.com/ws/MovieService/movieSearch" />
			<wsdl:input>
				<soap:body use="literal" />
			</wsdl:input>
			<wsdl:output>
				<soap:body use="literal" />
			</wsdl:output>
		</wsdl:operation>
	</wsdl:binding>
	<wsdl:service name="MovieService">
		<wsdl:port binding="mov:MovieServiceSOAP" name="MovieServiceSOAP">
			<soap:address location="http://www.example.org/" />
		</wsdl:port>
	</wsdl:service>
</wsdl:definitions>

2. Create Mule Project in Anypoint Studio and Place Contract Files

Create a Mule project in Anypoint Studio and place the defined WSDL to the location src/main/wsdl as demonstrated below.

Image title

3. Create a Flow With an HTTP Endpoint

Image title

I configured the HTTP endpoint port as 9090 and path as /contract.

4. Configure CXF Component

Mule has a CXF component in the Component palette for configuring JAX-WS-based web services. CXF framework is the implementation of the JAX-WS specification. Drag and drop CXF component from the Component palette.

Image title

Configure the CXF component as follows:

Image title

The sources are generated from the WSDL document by the CXF framework:

Image title

5. Implement SEI and Configure the Implementation as a Java Component 

Create a package for placing the implementation class:

Image title

Here is the implementation for the generated Service Endpoint Interface (SEI). For the sake of simplicity, we hard coded the implementation. 

package com.ss.source.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;

import com.ss.source.MovieService;
import com.ss.source.ObjectFactory;
import com.ss.source.ShowType;


@WebService(targetNamespace = "http://ss.com/ws/MovieService/", name = "MovieService")
@XmlSeeAlso({
 ObjectFactory.class
})
public class MovieServiceImpl implements MovieService {

 @Override
 @WebMethod(action = "http://ss.com/ws/MovieService/movieSearch")
 @RequestWrapper(localName = "movieSearch", targetNamespace = "http://ss.com/ws/MovieService/", className = "com.ss.ws.MovieSearchRequestType")
 @ResponseWrapper(localName = "movieSearchResponse", targetNamespace = "http://ss.com/ws/MovieService/", className = "com.ss.ws.MovieSearchResponseType")
 @WebResult(name = "showDetails", targetNamespace = "")
 public List < ShowType > movieSearch(
  @WebParam(name = "location", targetNamespace = "") java.lang.String location,
  @WebParam(name = "date", targetNamespace = "") javax.xml.datatype.XMLGregorianCalendar date,
  @WebParam(name = "movieName", targetNamespace = "") java.lang.String movieName
 ) {
  List < ShowType > shows = new ArrayList < ShowType > ();
  if (movieName.equalsIgnoreCase("Logan") && location.equalsIgnoreCase("hyderabad")) {
   ShowType showType = new ShowType();
   showType.setCinemaName("INOX Multiplex");
   showType.setShowTimes(Arrays.asList("10:00 AM", "2:00 PM", "7:00 PM"));
   shows.add(showType);
  }
  return shows;
 }

}

Drag and drop the Java component from the Component palette and configure as demonstrated below:

Image title

The flow after all configurations:

< ? xml version = "1.0"
encoding = "UTF-8" ? >

 < mule xmlns : http = "http://www.mulesoft.org/schema/mule/http"
xmlns: cxf = "http://www.mulesoft.org/schema/mule/cxf"
xmlns = "http://www.mulesoft.org/schema/mule/core"
xmlns: doc = "http://www.mulesoft.org/schema/mule/documentation"
xmlns: spring = "http://www.springframework.org/schema/beans"
xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi: schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http: //www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
 http: //www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
 http: //www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/current/mule-cxf.xsd">
 < http: listener - config name = "HTTP_Listener_Configuration"
host = "localhost"
port = "9090"
doc: name = "HTTP Listener Configuration" / >
 < cxf: configuration name = "CXF_Configuration"
enableMuleSoapHeaders = "true"
initializeStaticBusInstance = "true"
doc: name = "CXF Configuration" / >
 < flow name = "contract_firstFlow" >
 < http: listener config - ref = "HTTP_Listener_Configuration"
path = "/contract"
doc: name = "HTTP" / >
 < cxf: jaxws - service configuration - ref = "CXF_Configuration"
serviceClass = "com.ss.source.MovieService"
doc: name = "CXF" / >
 < component class = "com.ss.source.impl.MovieServiceImpl"
doc: name = "Java" / >
 < /flow> < /mule>

Run the flow from Anypoint studio.

Test the Service using http://localhost:9090/contract?wsdl.

Open the SOAP UI and create the new SOAP project using the above WSDL URL.

Test the project using the new request as demonstrated below:

Image titleCongrats! You got the response as per the implementation. 

Your API is not enough. Learn why (and how) leading SaaS providers are turning their products into platforms with API integration in the ebook, Build Platforms, Not Products from Cloud Elements.

Topics:
mulesoft ,anypoint ,web service ,wsdl ,tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}