I've just finished reading about SOAP via Spring-WS in "Spring in Action", 2nd edition, by Craig Walls from Manning Publications Co. They write about Contract First, much like the Spring docs, with making a message and method XML and then transforming that to XSD and then again to WSDL, while wiring up the marshalling and service path in Spring.
I must admit, I'm not convinced. Why is this a better path than, let's say, making a service interface and generating my service based on that interface? That's quite close to defining my REST #Controllers in Spring3. Do I have options of going a path like this with making SOAP webservices with Spring?
Also: I'd like to duplicate an already existing webservice. I have its WSDL and I can have my service placed instead of it. Is this recommended at all? If so, what's the recommended approach?
Cheers
Nik
I think you must have your wires crossed.
Contract first means defining a WSDL, and then creating Java code to support this WSDL.
Contract last means creating your Java code, and generating a WSDL later.
The danger with contract last is if your WSDL is automatically generated from your Java code, and you refactor your Java code, this causes your WSDL to change.
Spring-WS only supports contract first
2.3.1. Fragility
As mentioned earlier, the
contract-last development style
results in your web service contract
(WSDL and your XSD) being generated
from your Java contract (usually an
interface). If you are using this
approach, you will have no guarantee
that the contract stays constant over
time. Each time you change your Java
contract and redeploy it, there might
be subsequent changes to the web
service contract.
Aditionally, not all SOAP stacks
generate the same web service contract
from a Java contract. This means
changing your current SOAP stack for a
different one (for whatever reason),
might also change your web service
contract.
When a web service contract changes,
users of the contract will have to be
instructed to obtain the new contract
and potentially change their code to
accommodate for any changes in the
contract.
In order for a contract to be useful,
it must remain constant for as long as
possible. If a contract changes, you
will have to contact all of the users
of your service, and instruct them to
get the new version of the contract.
Toolkit's point about Java interfaces being more brittle is correct, but I think there's more.
Just like there's an object-relational impedance mismatch, there's also an object-XML mismatch. The Spring web service docs do a fine job of explaining how collections and the rest can make generating an XML document from a Java or .NET class problematic.
If you take the Spring approach and start with a schema you'll be better off. It'll be more stable, and it'll allow "duck typing". Clients can ignore elements that they don't need, so you can change the schema by adding new elements without affecting them.
Related
In spring-ws reference documentation, they say that it uses a contract-first approach (i.e. WSDL comes first), and that spring-ws even doesn't support a contract-last approach. But then, in the first example (page 15), a Java class is created, annotated with #Endpoint, and the WSDL is generated afterwards.
So, isn't it contract-last approach?
It's always a discussion if it's first or last. But you've got to start somewhere. I don't know exactly what you are referring to, but mostly the WSDL is generated based on the XSD. You might even have used the XSD to generate Java classes based on the elements in it. Those classes can be used for your endpoint mappings.
Spring-WS stands for Spring Web Services. Spring-WS focuses on document driven Web Services i.e. Contract-first development approach. Spring-WS aims at providing the best features of Web services along with the proven features of Spring like dependency injection, powerful mappings, support to ws-security etc..Spring-WS, the service contract can usually be generated automatically. But you must create the data contract yourself
This is more of a design-pattern question.
My client application [implemented and will run both as part of a scheduled batch job as well as a message processing application] makes SOAP over HTTP calls to a third party Engine to get some membership data. Since the underlying binding is done thought JAX-RPC, my SOAP response is eventually converted / copied into the generated client stubs.
Now, my question - Is it better to maintain my own domain objects and copy the data from the response objects of the service or is it OK if I can directly use the stub objects to do other processing!
Any suggestions?
This question is going to be somewhat subjective. I prefer to always translate to my own domain objects in case I ever need to swap out the web service implementation. If they ever change over to RESTful web services or just simply change up their wsdl on a version upgrade, you may be out of luck if you are using the stub classes throughout your application.
There are cons to this practice though:
You will need to maintain a similar set of classes
If the service never changes, you wont see any returns on your effort
You can always change this later if it proves useful
I am early on in a REST implementation and have recently learned that we could be putting our JAX-RS annotations on our Java service interfaces rather than the class implementations.
To me it seems like this could result in a clean class file, but might also result in developers have to constantly muddle between files.
What are the pros and cons of each approach?
You should put it in an interface. Rather, my practice requires me to put it into an interface, because my client and server sides are sharing the same jax-rs definition.
I am inclined to use jax-rs for REST-RPC.
The reason for REST is to allow an web service URL API to be serviceable and "clientable" by any programming framework.
The use of jax-rs restricts us to using java on the server side.
The use of jax-rs for REST-RPC restricts us to using java on both server and client sides.
What is REST-RPC?
In a not too convoluted attitude of explanation, RPC is a way of calling a function/method on the client, which when sent over the wire is serviced by the server such that the same function/method exists on the server side.
RestEasy allows you to use the jax-rs definition on the client-side to call the same function serviced on the server side.
RestyGWT, too, with some modification to the interface to specify a callback method would allow you to (somewhat) use the jax-rs definition on both client and server side. You simply have to write a script to move the return type to the type argument of the callback method.
You might question why restrict ourselves to performing java on both sides? Would that not defeat one of the purposes in life of REST? I think jax-rs REST-RPC is a convenient route to implementing and testing a jax-rs service. If you wanted to implement a jax-rs service, you probably would do it initially in Java on both sides anyway. And then when your service gets off the ground, you could start writing PHP or python clients.
Writing your jax-rs in interface files would allow you to publish your interface for client side operations. This is especially true for REST-RPC. However, you could run enunciate over your jax-rs definition to publish your web service API to non-java programmers.
I have some ongoing rambling on this subject...
http://h2g2java.blessedgeek.com/2011/11/gwt-with-jax-rs-aka-rpcrest-part-0.html.
I think I have to respectfully partially disagree with Blessed Geek here. What is mentioned is a very specific use case which requires the usage of annotations on the interface.
In my own experience, I have encountered cases where the framework either by design or by bug does not respond properly to placing annotations on the interface. For example, Apache CXF does not properly process #PUT requests with #PathParams defined in the path when you place the annotations on the interface. Don't ask me why. CXF is not alone in this; Spring Security suffers from similar limitations in placing annotations on interfaces. So this is a counterpoint to the one mentioned above.
In cases where you are free to choose where to place the annotations, I would urge you to consider what makes sense from a standpoint of intention, design, and ease of development.
As a philosophical argument, some folks say that placing annotations on interfaces is another form of contract programming- you are saying that implementations will abide by certain rules.
The other side of that coin (depending on your definition of interfaces) is that interfaces should not care about what steps their implementors take in achieving the goal defined in the method contract. For example, why place a #Transactional annotation on an interface when you might have two implementations, one of which has no idea what a "transaction" might be?
In practice, the lines blur. In the case of defining a restful endpoint, you may prefer to place the proper annotations on the interface. I think this makes sense in most cases; you probably won't have multiple implementations where the same method signature responds to different HTTP verbs. However you could come up with a situation where different implementations prefer to consume and produce different media types.
So, the big idea here is "it depends." But hopefully this is some food for thought for those who may stumble upon this question.
I had a similar question when using JAX-RS with JAX-B. My hope was to use JAX-B annotations on interfaces not classes. This doesn't work as I expected, the reason is due to the unmarshaller. To solve my issues, I ended up using classes. Here is a description of why and what I found.
I recently wrote some data access methods (plain old Java) that use immutable objects for both the request objects and the resulting data objects. I like the immutable objects because they prevent a good deal of confusion from appearing in the client code which I've seen in the past when people attempt to mutate and reuse objects.
Anyway, that was months ago. Now a colleague is having trouble with some web service generation stuff (attempting to expose my methods) which expects everything everywhere to be a JavaBean.
My question is: does web service stuff generation stuff always mandate use of JavaBeans? Is there another way?
Most web service frameworks provide some way for you to supply custom serializers/deserializers for types. Sounds like that is what you need here.
If it isn't clear why that's necessary, it is because the framework needs to know how to translate your Java class into XML and vice versa. Serializing and deserializing JavaBeans (classes with get and set properties) is easy if you follow the naming strategy, but you should also be able to supply your custom type serializers for classes that do not follow the bean pattern.
There are two general approaches to Web service development: top-down and bottom-up.
In the top-down approach, a Web service is based on the Web service interface and XML types, defined in WSDL and XML Schema Definition (XSD) files. The developer first designs the implementation of the Web service by creating a WSDL file. From this skeleton Java classes can be created to which the developer can add the required code. This skeleton implementation serves as an interface with the business logic. This process is also one of the J2EE standard - JAX-RPC based API for Web services which defines standard mappings between Java classes and XML types.
In the bottom-up approach, a Web service is created based on the existing business logic in Java beans or EJBs. A WSDL file is generated to describe the resulting Web service interface. Seems like your colleague is using this approach.
I would recommend a top-down rather than a bottom approach as you would have more control on the interface definitions and naming. Also your colleague could use your existing classes through the tooling generated skeleton interface.
I am working on an existing Java project with a typical services - dao setup for which only a webapplication was available. My job is to add webservices on top of the services layer, but the webservices have their own functional analysis and datamodel. The functional analyses ofcource focuses on what is possible in the different service methods.
As good practice demands, we used the WSDL first strategy and generated JAXB bound Java classes and a SEI for the webservices. After having implemented the webservices partially, we noticed a 70% match between the datamodel. This resulted in writing converters which take the webservice JAXB classes and map them with the service layer classes.
Customer customer = new Customer();
customer.setName(wsCustomer.getName());
customer.setFirstName(wsCustomer.getFirstName();
..
This is a very obvious example, some other mappings where little more complicated.
Can anyone give his best practices, experiences, solutions to this kind of situations?
Are any of these frameworks usefull?
http://transmorph.sourceforge.net/wiki/index.php/Main_Page
http://ezmorph.sourceforge.net/
Please don't start a discussion about WSDL first vs code first.
I am experiencing the same issue on my project. I created a factory for the generated objects and use it for creating objects.
Customer customer = factory.createCustomer(wsCustomer);
Which isolates the construction code, w/o altering the generated code.
I think the real question is... how much of the code generators do you want to use in the future, and can you get them to generate what you're doing now.
Converting everything to your current data model is a good idea, if you don't care about the code generation capabilities of your tools, or they can adapt to what you want.