SOAP API parameter best practice - web-services

I have a set of soap webservices that are tightly coupled to an application within the same architecture but I need it to also be an API for other applications to hook into.
At the moment, the services use a parameter (and method) structure like this
Entity GetEntity(int entityId)
Entity GetEntityByName(string entityName)
.... etc.
In the case of creates I use:
void CreateEntity(Entity entity)
I am wondering though would it be better to do it like this:
EntityResponse GetEntity(EntityRequest requestObj) .....
and in the requestObj I have id, entityName and depending what the user supplies, I can perform either function.
and for the create it would be:
CreateEntityResponse CreateEntity(CreateEntityRequest requestObj).
My thinking is that by doing it like this, the API can change internally...add new parameters etc without immediately breaking any integration that has already been done.

I think there are several design principles that you may want to consider:
1) Database Entity vs Data Transport Object DTO
Looks like those Entities come directly from a database mapping? Just exposing your Entities as API, is basically a fancy SQL Query browser. It's not necessarily wrong but you will achieve better de-coupling if you would expose DTO's in the API.
The DTO's could be more future proof then the Entities and more generic.
2) SOAP vs REST
If you want to achieve a maximum of future proofing you might want to consider REST. With the REST specification you have more options to extend the API later.
For instance if you look at APIs like Facebook they purely pass in parameters and then you receive in return a key-value map of the parameters you passed in. So very generic.
In SOAP you would always end up in defining all of those eventual attributes upfront. You basically need to introduce placeholders et cetera.
There is certainly a reason why SOAP is a good contract protocol and has advantages like code generating tools are more up to date and lots more. But with REST you could be even more flexible while loosing some of the goodies you had in SOAP.
This is also a very good read:
https://www.mulesoft.com/lp/whitepaper/api/secrets-great-api
or generally the RAML design spec from Mule is a very powerful tool when it comes to designing REST APIs.

Related

Nested router vs filters

I'm very new to API implementation from ground up and I needed some advice on what the standard or the best approach in my API structure is.
Currently my implementation includes nested routers (drf-nested-routers package) such as
"www.thissite.com/store/21/products/1/"
Now as I dig deeper in django I've uncovered that there are filters that allow me to do the exact same operation above with a little less code like this
"www.thissite.com/products/?store__id=21&id=1"
My question is which one is best practice and why?
Both are best practices, since REST does not constrain URI design. I call www.thissite.com/store/21/products/1/ hierarchical URI design and www.thissite.com/products/?store__id=21&id=1 flat URI design. I like the flat design better, but that is just my personal taste. If you need both store-id and product-id in order to identify a product then these URIs are okay and any URIs are okay with these variables, so for example x/y/z/:pid/q/r/s/:sid, etc... By REST the URI (template) creation is the responsibility of the service and the clients consumes only the URIs it gets from the service in forms of hyperlinks. So from REST client perspective the URI structure does not matter. We tend to design nice URIs only to keep the REST service routing logic clear.
If a product is always related to a store (which seems to be the case, given the names), then it's considered a best practice for REST, to maintain an hierarchical structure by making products a subresource of stores. Thus I would suggest you to follow the first aforementioned approach.
The filtering should be used to filter resources based on some internal characteristics (e.g class attributes), not based on relations to other resources.

REST vs RPC for a C++ API

I am writing a C++ API which is to be used as a web service. The functions in the API take in images/path_to_images as input parameters, process them, and give a different set of images/paths_to_images as outputs. I was thinking of implementing a REST interface to enable developers to use this API for their projects (independent of whatever language they'd like to work in). But, I understand REST is good only when you have a collection of data that you want to query or manipulate, which is not exactly the case here.
[The collection I have is of different functions that manipulate the supplied data.]
So, is it better for me to implement an RPC interface for this, or can this be done using REST itself?
Like lcfseth, I would also go for REST. REST is indeed resource-based and, in your case, you might consider that there's no resource to deal with. However, that's not exactly true, the image converter in your system is the resource. You POST images to it and it returns new images. So I'd simply create a URL such as:
POST http://example.com/image-converter
You POST images to it and it returns some array with the path to the new images.
Potentially, you could also have:
GET http://example.com/image-converter
which could tell you about the status of the image conversion (assuming it is a time consuming process).
The advantage of doing it like that is that you are re-using HTTP verbs that developers are familiar with, the interface is almost self-documenting (though of course you still need to document the format accepted and returned by the POST call). With RPC, you would have to define new verbs and document them.
REST use common operation GET,POST,DELETE,HEAD,PUT. As you can imagine, this is very data oriented. However there is no restriction on the data type and no restriction on the size of the data (none I'm aware of anyway).
So it's possible to use it in almost every context (including sending binary data). One of the advantages of REST is that web browser understand REST and your user won't need to have a dedicated application to send requests.
RPC presents more possibilities and can also be used. You can define custom operations for example.
Not sure you need that much power given what you intend to do.
Personally I would go with REST.
Here's a link you might wanna read:
http://www.sitepen.com/blog/2008/03/25/rest-and-rpc-relationship/
Compared to RPC, REST's(json style interface) is lightweight, it's easy for API user to use. RPC(soap/xml) seems complex and heavy.
I guess that what you want is HTTP+JSON based API, not the REST API that claimed by the REST author
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Can you help clarify some points regarding RESTful services and Code Generation?

I've been struggling with understanding a few points I keep reading regarding RESTful services. I'm hoping someone can help clarify.
1a) There seems to be a general aversion to generated code when talking about RESTful services.
1b) The argument that if you use a WADL to generate a client for a RESTful service, when the service changes - so does your client code.
Why I don't get it: Whether you are referencing a WADL and using generated code or you have manually extracted data from a RESTful response and mapped them to your UI (or whatever you're doing with them) if something changes in the underlying service it seems just as likely that the code will break in both cases. For instance, if the data returned changes from FirstName and LastName to FullName, in both instances you will have to update your code to grab the new field and perhaps handle it differently.
2) The argument that RESTful services don't need a WADL because the return types should be well-known MIME types and you should already know how to handle them.
Why I don't get it: Is the expectation that for every "type" of data a service returns there will be a unique MIME type in existence? If this is the case, does that mean the consumer of the RESTful services is expected to read the RFC to determine the structure of the returned data, how to use each field, etc.?
I've done a lot of reading to try to figure this out for myself so I hope someone can provide concrete examples and real-world scenarios.
REST can be very subtle. I've also done lots of reading on it and every once in a while I went back and read Chapter 5 of Fielding's dissertation, each time finding more insight. It was as clear as mud the first time (all though some things made sense) but only got better once I tried to apply the principles and used the building blocks.
So, based on my current understanding let's give it a go:
Why do RESTafarians not like code generation?
The short answer: If you make use of hypermedia (+links) There is no need.
Context: Explicitly defining a contract (WADL) between client and server does not reduce coupling enough: If you change the server the client breaks and you need to regenerate the code. (IMHO even automating it is just a patch to the underlying coupling issue).
REST helps you to decouple on different levels. Hypermedia discoverability is one of the goods ones to start with. See also the related concept HATEOAS
We let the client “discover” what can be done from the resource we are operating on instead of defining a contract before. We load the resource, check for “named links” and then follow those links or fill in forms (or links to forms) to update the resource. The server acts as a guide to the client via the options it proposes based on state. (Think business process / workflow / behavior). If we use a contract we need to know this "out of band" information and update the contract on change.
If we use hypermedia with links there is no need to have “separate contract”. Everything is included within the hypermedia – why design a separate document? Even URI templates are out of band information but if kept simple can work like Amazon S3.
Yes, we still need a common ground to stand on when transferring representations (hypermedia), so we define your own media types or use widely accepted ones such as Atom or Micro-formats. Thus, with the constraints of basic building blocks (link + forms + data - hypermedia) we reduce coupling by keeping out of band information to a minimum.
As first it seems that going for hypermedia does not change the impact of change :) : But, there are subtle differences. For one, if I have a WADL I need to update another doc and deploy/distribute. Using pure hypermedia there is no impact since it's embedded. (Imagine changes rippling through a complex interweave of systems). As per your example having FirstName + LastName and adding FullName does not really impact the clients, but removing First+Last and replacing with FullName does even in hypermedia.
As a side note: The REST uniform interface (verb constraints - GET, PUT, POST, DELETE + other verbs) decouples implementation from services.
Maybe I'm totally wrong but another possibility might be a “psychological kick back” to code generation: WADL makes one think of the WSDL(contract) part in “traditional web services (WSDL+SOAP)” / RPC which goes against REST. In REST state is transferred via hypermedia and not RPC which are method calls to update state on the server.
Disclaimer: I've not completed the referenced article in detail but I does give some great points.
I have worked on API projects for quite a while.
To answer your first question.
Yes, If the services return values change (Ex: First name and Last name becomes Full Name) your code might break. You will no longer get the first name and last name.
You have to understand that WADL is a Agreement. If it has to change, then the client needs to be notified. To avoid breaking the client code, we release a new version of the API.
The version 1.0 will have First Name and last name without breaking your code. We will release 1.1 version which will have the change to Full name.
So the answer in short, WADL is there to stay. As long as you use that version of the API. Your code will not break. If you want to get full name, then you have to move to the new versions. With lot of code generation plugins in the technology market, generating the code should not be a issue.
To answer your next question of why not WADL and how you get to know the mime types.
WADL is for code generation and serves as a contract. With that you can use JAXB or any mapping framework to convert the JSON string to generated bean objects.
If not WADL, you don't need to inspect every element to determine the type. You can easily do this.
var obj =
jQuery.parseJSON('{"name":"John"}');
alert( obj.name === "John" );
Let me know, If you have any questions.

Well-behaving RESTful Client Interactions

I have what seems to be a fairly simple question about implementing a data access client that strictly adheres to REST architectural principles. To start, let's assume I have a well-behaving REST API that I want to consume using a Django application. I'll start by discovering what services are available (edited for follow-up):
GET example.com/services/ HTTP/1.1
HTTP/1.1 200 OK
<?xml version="1.0" encoding="UTF-8"?>
<services>
<service>
<name>Widgets</name>
<link>http://example.com/services/widgets/</link>
<item_link>http://example.com/services/widgets/{widget_id}/</item_link>
</service>
<service>
<name>Factories</name>
<link>http://example.com/services/factories/</link>
<item_link>http://example.com/services/factories/{factory_id}/</item_link>
</service>
...
</services>
Now, since I'm building a Django application based around consuming this API, how would I continue to keep exploring these services RESTfully? To adhere to REST principles, my application must be driven by the hypermedia received. I suppose the first step is easy enough -- interacting with a service by the name given. I set up a Django view as follows:
def get_service(request, service_name):
doc = etree.parse(urllib.urlopen('http://example.com/services/'))
uri = doc.xpath("service/name[.='%s']/following-sibling::*" % service_name)[0].text
...
From which I'll perform another request (edited for follow-up):
GET example.com/services/widgets/ HTTP/1.1
HTTP/1.1 200 OK
<?xml version="1.0" encoding="UTF-8"?>
<widgets>
<item_link>http://example.com/services/widgets/{widget_id}/</item_link>
<widget>
<id>1</id>
<name>Whizbang Foobar</name>
<link>http://example.com/services/widgets/1</link>
</widget>
...
</widgets>
Now I'll display a simple list of widgets in a rendered Django template. From here though, how do I continue to interact with this service RESTfully? Perhaps I've befuddled myself into confusion, but the only reasonable things I can come up with are implementing a numerous amount of application views or a thin Django data model to persist the service URI.
My main concern boils down to that this is trivial to do without strictly adhering to REST architectural guidelines, but I feel like I've missed the boat completely in trying to do so. I understand designing proper REST APIs and clients isn't "easy", but it seems that I'm in dire need of a similar example to work through the actual implementation.
I apologize for the length and verbosity of the question and the inevitable facepalming of wizened readers.
Follow-up:
Is the following a valid way (using URI templates) of implementing these interactions? For demonstration purposes (in lieu of a more abstract implementation), another Django view to retrieve a resource collection item:
def get_item(request, service_name, item_id):
doc = etree.parse(urllib.urlopen('http://example.com/services/'))
uri = doc.xpath("service/name[.='%s']/following-sibling::item_link" % service_name)[0].text
...
Then the subsequent request:
GET example.com/services/widgets/1 HTTP/1.1
HTTP/1.1 200 OK
<?xml version="1.0" encoding="UTF-8"?>
<widget>
<id>1</id>
<name>Whizbang Foobar</name>
<tags>foo bar baz ham eggs</tags>
<index_link>http://example.com/services/widgets/</index_link>
</widget>
My main concern boils down to that this is trivial to do without strictly adhering to REST architectural guidelines, but I feel like I've missed the boat completely in trying to do so. I understand designing proper REST APIs and clients isn't "easy", but it seems that I'm in dire need of a similar example to work through the actual implementation.
The best example I've been able to find is the Sun Cloud API. Most of the documentation describes the various media types used by the system, which seems to be the key to pulling this kind of thing off.
I find that it helps to be writing your client at the same time you're developing your API. That way you can spot what's likely to make your API a pain to code for right away and fix the problem.
It isn't easy. If you follow the HATEOAS constraint to its logical conclusion, each media type you define will be handled by one of a family of clients. To the extent that you can make all of your resources follow a similar pattern of behavior, your job of writing clients will become easier.
For example, you could define a media type 'Index' that simply lists related resources. Index defines links for pagination, getting items in the list, finding items by name, etc.
Then, you might define a base media type called 'Item'. Item has a link for displaying its parent Index, updating/deleting itself, etc. Your resource Widget could then be represented by two different media types - one Index and one based on Item.
You could begin by implementing a single class that handles the Index media type. Then you could write a base class that handles all common Item media type behavior. Finally, you could write a Widget client that handles all widget-specific behavior and which extends the Item client. These clients could expose their functionality (availability of more links and data fields) in an idiomatic way for the language they're written in.
Processing a response from your server would then be a matter of matching the mime type of the response to one of the clients you've written.
In other words, even though the client for your service as a whole would be made up of many clients of limited scope, they would each be based on common behaviors and so could be implemented in a DRY way.
From my experience the REST model makes much more sense if the representations and their contained links are translated directly to a client UI. In this scenario it is the user that directs the exploring of the REST interface.
Often I see people trying to use REST interfaces as a kind of HTTP based data access layer. With this mental model, hyperlinked data provides little more than structural data relationships. It becomes difficult to build application behaviour on top of that interface without violating RESTful constraints.
I like to think of a RESTful interface as delivering UI content to an application that is going to render that content with some arbitrary technology. Unfortunately, REST is frequently compared to web services which, in my opinion, fit in a different architectural layer. Web services deliver data that is to be processed by a client application. RESTful interfaces should deliver content that will be rendered to the user.
Sure you can use a REST interface to deliver data to remote applications but think of it as simplified screen scraping.
When writing a client for REST interface I find it useful to imagine that I am writing a custom web browser that only understands the media-types that are delivered by that RESTful interface and is hard-coded to start at a specific URL and there is no address bar!
Sun Cloud API documentation is a great example of a RESTful API, focusing on the media types.
If I understand your question correctly, you want to explore an unknown service, correct?
If so, then you could, for example continue with an OPTIONS request to the "widget" resource, to see which HTTP methods it supports (these should be listed in the Allow header of the response).
You can then do the same for all URIs found in <link rel="whatever"> elements. If a resource found this way indicates that it supports GET, then fetch it and repeat ...
This way you should be able to explore all nested resources.
This kind of exploration will of course only get you so far, because to really interact with the service, you will need to know about its media types (or representations), and what the different <link rel="whatever"> actions you found actually mean. This step can't be automated, you'll have to read the documentation for the service and build you client accordingly. I suggest reading the article "How to GET a Cup of Coffee", which I think explains this interaction very well.

Is it possible to return objects from a WebService?

Instead of returning a common string, is there a way to return classic objects?
If not: what are the best practices? Do you transpose your object to xml and rebuild the object on the other side? What are the other possibilities?
As mentioned, you can do this in .net via serialization. By default all native types are serializable so this happens automagically for you.
However if you have complex types, you need to mark the object with the [Serializable] attribute. The same goes with complex types as properties.
So for example you need to have:
[Serializable]
public class MyClass
{
public string MyString {get; set;}
[Serializable]
public MyOtherClass MyOtherClassProperty {get; set;}
}
If the object can be serialised to XML and can be described in WSDL then yes it is possible to return objects from a webservice.
Yes: in .NET they call this serialization, where objects are serialized into XML and then reconstructed by the consuming service back into its original object type or a surrogate with the same data structure.
Where possible, I transpose the objects into XML - this means that the Web Service is more portable - I can then access the service in whatever language, I just need to create the parser/object transposer in that language.
Because we have WSDL files describing the service, this is almost automated in some systems.
(For example, we have a server written in pure python which is replacing a server written in C, a client written in C++/gSOAP, and a client written in Cocoa/Objective-C. We use soapUI as a testing framework, which is written in Java).
It is possible to return objects from a web service using XML. But Web Services are supposed to be platform and operating system agnostic. Serializing an object simply allows you to store and retrieve an object from a byte stream, such as a file. For instance, you can serialize a Java object, convert that binary stream (perhaps via a Base 64 encoding into a CDATA field) and transfer that to service's client.
But the client would only be able to restore that object if it were Java-based. Moreover, a deep copy is required to serialize an object and have it restored exactly. Deep copies can be expensive.
Your best route is to create an XML schema that represents the document and create an instance of that schema with the object specifics.
.NET automatically does this with objects that are serializable. I'm pretty sure Java works the same way.
Here is an article that talks about object serialization in .NET:
http://www.codeguru.com/Csharp/Csharp/cs_syntax/serialization/article.php/c7201
#Brian: I don't know how things work in Java, but in .net objects get serialized down to XML, not base64 strings. The webservice publishes a wsdl file that contains the method and object definitions required for your webservice.
I would hope that nobody creates webservices that simply create a base64 string
Daniel Auger:
As others have said, it is possible.
However, if both the service and
client use an object that has the
exact same domain behavior on both
sides, you probably didn't need a
service in the first place.
lomax:
I have to disagree with this as it's a
somewhat narrow comment. Using a
webservice that can serialize domain
objects to XML means that it makes it
easy for clients that work with the
same domain objects, but it also means
that those clients are restricted to
using that particular web service
you've exposed and it also works in
reverse by allowing other clients to
have no knowledge of your domain
objects but still interact with your
service via XML.
# Lomax: You've described two scenarios. Scenario 1: The client is rehydrating the xml message back into the exact same domain object. I consider this to be "returning an object". In my experience this is a bad choice and I'll explain this below. Scenario 2: The client rehydrates the xml message into something other than the exact same domain object: I am 100% behind this, however I don't consider this to be returning a domain object. It's really sending a message or DTO.
Now let me explain why true/pure/not DTO object serialization across a web service is usually a bad idea. An assertion: in order to do this in the first place, you either have to be the owner of both the client and the service, or provide the client with a library to use so that they can rehydrate the object back into it's true type. The problem: This domain object as a type now exists in and belongs to two semi-related domains. Over time, behaviors may need to be added in one domain that make no sense in the other domain and this leads to pollution and potentially painful problems.
I usually default to scenario 2. I only use scenario 1 when there is an overwhelming reason to do so.
I apologize for being so terse with my initial reply. I hope this clears things up to a degree as far as what my opinion is. Lomax, it would seem we half agree ;).
JSON is a pretty standard way to pass objects around the web (as a subset of javascript). Many languages feature a library which will convert JSON code into a native object - see for example simplejson in Python.
For more libraries for JSON use, see the JSON webpage
As others have said, it is possible. However, if both the service and client use an object that has the exact same domain behavior on both sides, you probably didn't need a service in the first place.
As others have said, it is possible.
However, if both the service and
client use an object that has the
exact same domain behavior on both
sides, you probably didn't need a
service in the first place.
I have to disagree with this as it's a somewhat narrow comment. Using a webservice that can serialize domain objects to XML means that it makes it easy for clients that work with the same domain objects, but it also means that those clients are restricted to using that particular web service you've exposed and it also works in reverse by allowing other clients to have no knowledge of your domain objects but still interact with your service via XML.