Table of Contents
Introduction
The Sencha data package offers a number of different proxies to connect your application to all kinds of data. With the release of Ext JS 4.1.2 in Sencha Complete: Team, developers can now point to SOAP web services. With SOAP being one of the most popular web service protocols out there, this will allow developers a new option for connecting their applications to data.
The SOAP proxy works just like the other proxies, all you need to do is configure the proxy on your store, and you don’t have to worry about the details of handling the communication requests.
What is SOAP
SOAP (Simple Object Access Protocol) is an XML-based protocol that allows applications to communicate with remote web services. SOAP has a number of advantages. It’s protocol-independent, meaning you can transport SOAP messages over HTTP, SMTP or JMS. It also provides a strict contract that any client is required to follow in terms of object and method communication. However, due to it’s strict contract rules, it’s a bit slower when compared to using other communication protocols such as REST. The functionality in a SOAP service is defined in a Web Services Description Language (WSDL) file. It will show clients what methods and datatypes it’s expecting, so you can develop for that contract.
SOAP clients interact with the service by passing around a SOAP envelope, which is a specially formatted XML document. The envelope consists of an optional header, to pass application specific information with the request, and a required body that contains the information specific to the request. Below is a sample request showing the different envelopes used for the request and response of a simple service named getPeople and the returning Person objects.
Sample Request:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <getPeople xmlns="http://samples/xsd"></getPeople> </soap:Body> </soap:Envelope>
Sample Response:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <ns:getPeopleResponse xmlns:ax219="http://rpc.xml.coldfusion/xsd" xmlns:ns="http://samples/xsd"> <ns:return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns:Person"> <ns:firstName>Kevin</ns:firstName> <ns:id>1</ns:id> <ns:lastName>Kazmierczak</ns:lastName> </ns:return> </ns:getPeopleResponse> </soapenv:Body> </soapenv:Envelope>
Sample Application
To try out the new SOAP proxy, I built a sample CRUD application that communicates with a ColdFusion web service I’ve created using a ColdFusion Component (CFC). ColdFusion provides a really simple way to generate the SOAP WSDL file for you by just marking your CFC methods as access “remote”.
The application shows a simple grid of data provided via the SOAP proxy. You can double click on a record to edit or delete it. There is a plus button in the top right to insert new records. During all of these interactions, I recommend you have a tool like the Chrome developer tools or Firebug running which will allow you to view the network requests, so you can see whats going on behind the scenes.
Server Setup
I’ve setup the server using ColdFusion 10 deployed on an Apache Tomcat 7 server. Inside the ColdFusion application container, I’ve created a CFC with 4 remote methods that are used to create, read, update, and delete a simple ‘Person’ object. The service is just working with mock data that gets reset on the next use, but works for demonstration purposes.
Data Setup
The model object is a very simple Person object consisting of a few basic properties.
Ext.define('SampleApp.model.Person', { extend: 'Ext.data.Model', fields: [ { name: 'id', type: 'int' }, { name: 'firstName', type: 'string' }, { name: 'lastName', type: 'string' } ] });
Where things get specific to the SOAP proxy is inside the Store object:
Ext.define('SampleApp.store.People', { extend:'Ext.data.Store', model:'SampleApp.model.Person', autoLoad:true, proxy: { type: 'soap', url: '/cfusion/samples/People.cfc', api: { create: 'createPerson', read: 'getPeople', update: 'updatePerson', destroy: 'deletePerson' }, soapAction: { create: 'http://localhost:8080/cfusion/samples/People.cfc', read: 'http://localhost:8080/cfusion/samples/People.cfc', update: 'http://localhost:8080/cfusion/samples/People.cfc', destroy: 'http://localhost:8080/cfusion/samples/People.cfc' }, operationParam: 'operation', targetNamespace: 'http://samples/xsd' reader: { type: 'soap', record: 'ns|return', namespace: 'ns' } } });
There are a lot of options in there, so let’s take a closer look at what’s going on in there.
- type: ‘soap’
- Sets the proxy to use the new SOAP proxy.
- url: ‘/cfusion/People.cfc’
- Provides the base URL used for the api methods you define. Due to browser security policies, this URL must be on the same domain as your application. If you need to access remote SOAP services, you’ll need to do a custom setup like a server side proxy service.
- api
- You define the SOAP operations that correspond to the create, read, update, destroy built in store actions. You only need to define the methods you are planning to use.
- soapAction
- Defines the URLs used for each of the CRUD methods. The SOAP specification requires this information to be passed in the request header.
- operationParam: ‘operation’
- Defines the name of the parameter in your SOAP service that points to the operation used with the CRUD request.
- targetNamespace: ‘http://samples/xsd’
- The XML namespace used to construct the SOAP envelope. You’ll want this to match up with what is defined in the WSDL contract.
- reader
- Sets up the SOAP reader for this proxy and tells it what to use for the record object when it parses the SOAP response. Also required is the namespace to use when parsing the response.
Once you have the store and the model setup, all you need to do is create a view that points to your data. Below is a sample grid view that shows the data from the store and the model.
Ext.define('SampleApp.view.ListView', { extend:'Ext.grid.Panel', title: 'Person List', alias: 'widget.listView', store: 'People', columns: [ { text: 'Id', flex: 1, dataIndex: 'id' }, { text: 'First Name', flex: 1, dataIndex: 'firstName' }, { text: 'Last Name', flex: 1, dataIndex: 'lastName' } ], tools: [{ type: 'plus' }] });
When you put all of that together, you’ll get a grid that looks like this:
Configuration Options
There are a few other options with the SOAP proxy that aren’t used in this example but are extremely helpful. If the SOAP service you are communicating with requires envelope objects in a specific format that’s not being generated automatically with the proxy, you can override how it creates them using the XTemplate strings. The proxy exposes the ability to overwrite any of the CRUD message envelopes. Below are two examples of how to override the base envelope and read objects templates.
proxy: { ... envelopeTpl: [ '<?xml version="1.0" encoding="utf-8" ?>', '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">', '{[values.bodyTpl.apply(values)]}', '</s:Envelope>' ], readBodyTpl: [ '<s:Body>', '<{operation} xmlns="{targetNamespace}">', '<tpl foreach="params">', '<{$}>{.}</{$}>', '</tpl>', '</{operation}>', '</s:Body>' ] }
Conclusion
The addition of the SOAP proxy makes it easy to connect your data stores to a whole new set of data. All of the options are there, so you can connect to existing SOAP services or new ones being built. Developers don’t need to worry about the details, all they need to do is configure the proxy and the framework takes care of the rest.
Resources
Sample Code
So, this is only available to those that purchased the Team edition of Sencha Complete?
There are a boat load of SOAP based services out there. But I still wouldn’t call them popular :)
https://www.google.com/search?q=define:popular&oq=define:popular
Nice. We have just started working on data connectors for our cloud dashboard application, http://www.otusanalytics.com/dashboards.html, built with Ext JS 4 and Rails. As is almost always the case, our first pass will be CSV files since any data app can spit them out, but then we need to look at more sophisticated ways to get data into the application over the web. Although, as Dmitry says, SOAP is still not that popular, it is a great way to connect data over the web. Thanks for the enhancement!!!
I am working on a web / mobile set of applications using Coldfusion 10 and web services for the insurance industry. Can we download the SOAP data proxy files if we do not have Team? Team is currently not well priced for independents even though we need such as this and native packaging.
Why people keep using XML while JSON is a far way better way?
JSON may be Simple, but it’s hardly the one-size-fits-all solution…
This article explains it better than I can in the next 30 seconds.
http://digitalbazaar.com/2010/11/22/json-vs-xml/
I translated it into Japanese.
http://www.xenophy.com/javascript/3778
Provision: Japan Sencha User Group
http://www.meetup.com/Japan-Sencha-User-Group/about/
Whoops. What a shame a genuinely interesting software release from Sencha has been undermined by a provocative claim. Anyone with their finger on the pulse of software development trends knows that usage of SOAP for a browser client/server relationship is declining relative to RESTful APIs.
I suggest the opening paragraph is reworded as “With SOAP being a prevalent web service protocol…”
I hope Sencha does not become another Microsoft with multiple ways of doing the same thing backed up with in-house evangelists who consider all options as “super exciting”.
@LoreZyra — Yes, this only available as a part of Complete Team.
@Bill — sorry to hear that, but today the SOAP proxy is only in Complete Team.
@camelCase — our goal is provide you with tools to let you connect to various types of backends. For large enterprises and businesses built around SOA, SOAP makes sense to connect to before they can move to REST/JSON.
Aditya,
I am looking forward to evaluate ‘Ext JS 4.1.2 in Sencha Complete: Team’ just for this new feature. I have a couple of quick questions:-
1) Is there support for WS-security (SAML tokens) or basic authentication ? For basic authentication where and how(encrypted/plain text) are the credentials stored ?
2) how are XML namespaces managed in SOAP requests and responses ?
thanks,
– Abhi
How about fixing the giant cataclysmic performance debacle first.
This is really cool! I just have one question about how you manage Namespaces in your SOAP XML…I recently had problems with a normal XML proxy and solved NAMESPACE issues by simply replacing them…Is there now support for them in ExtJS 4.1.2?
I welcome the addition of SOAP based services. There are still many fringe server side technologies that have yet to implement JSON, but do have battled tested SOAP as an option.
My only negative is that developers are having to hand crank the consumer code. Why not go the full distance and produce the stores and models from the WSDL? Or produce JavaScript stubs and let developers register functions in the same way we do with the Ext.Direct functions?
when will this be available for sencha architect?
Nice!
But … what to do if SOAP message using more than one namespace?