In WSDL, the wsdl:Fault element declares the structure of SOAP fault messages the service may return. Or more precisely, it declares the structure of the <detail> element of the SOAP fault message.
Q: What precisely is the purpose of this wsdl:Fault declaration? Does it specify that the SOAP fault message detail MUST have the declared namespace and structure? Or does it specify that the SOAP fault message detail typically has the declared namespace and structure? In other words, if a SOAP service returns SOAP faults with structure of the <detail> element having namespace other than declared in the WSDL, will the message be invalid with respect to the WSDL?
In my opinion, the wsdl:Fault declaration is just a suggestion. A SOAP fault may be returned by another layer than by the service itself (e.g. by a proxy gateway), and this layer may return an arbitrary content in the SOAP fault detail. Hence I deduce that if the service implementation returns a different fault detail than is declared in the WSDL, it should be fine, is it?
I haven't found any explicit answer to my question. But from various hints in various documentation on the internet I deduce that:
Fault message can contain any number of children of the <detail> element. Even such detail structures that are not declared in the WSDL. See e.g. Example 16-6.
Faults declared in WSDL are considered modeled faults, others are unmodeled faults. Modeled faults represent business logic faults, the other faults usually represent runtime/technical faults (see here).
Having multiple elements under the <detail> element does not contradict the WS-I Basic Profile. In particular, the requirement R1002 says:
R1002: A RECEIVER MUST accept faults that have any number of elements,
including zero, appearing as children of the detail element. Such
children can be qualified or unqualified.
So, to sum this up:
A service should return modeled faults for business errors. The consumers might handle these modeled faults in a special way, for example to retry the request with modified parameters. Unmodeled faults are used mainly for technical errors, validation errors and other runtime errors.
When you start returning an unmodeled fault instead of a modeled one, you might break the business logic for the consumer application.
Related
I have a service, which is exposed over HTTP. Most of traffic input gets into it via single HTTP GET endpoint, in which the payload is serialized and encrypted (RSA). The client system have common code, which ensures that the serialization and deserialization will succeed. One of the encoded parameters is the operation type, in my service there is a huge switch (almost 100 cases) that checks which operation is performed and executes the proper code.
case OPERATION_1: {
operation = new Operation1Class(basicRequestData, serviceInjected);
break;
}
case OPERATION_2: {
operation = new Operation2Class(basicRequestData, anotherServiceInjected);
break;
}
The endpoints have a few types, some of them are typical resource endpoints (GET_something, UPDATE_something), some of them are method based (VALIDATE_something, CHECK_something).
I am thinking about refactoring the API of the service so that it is more RESTful, especially in the resource-based part of the system. To do so I would probably split the endpoint into the proper endpoints (e.g. /resource/{id}/subresource) or RPC-like endpoints (/validateSomething). I feel it would be better, however I cannot make up any argument for this.
The question is: what are the advantages of the refactored solution, and what follows: what are the disadvantages of the current solution?
The current solution separates client from server, it's scalable (adding new endpoint requires adding new operation type in the common code) and quite clear, two clients use it in two different programming languages. I know that the API is marked as 0-maturity in the Richardson's model, however I cannot make up a reason why I should change it into level 3 (or at least level 2 - resources and methods).
Most of traffic input gets into it via single HTTP GET endpoint, in which the payload is serialized and encrypted (RSA)
This is potentially a problem here, because the HTTP specification is quite clear that GET requests with a payload are out of bounds.
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
It's probably worth taking some time to review this, because it seems that your existing implementation works, so what's the problem?
The problem here is interop - can processes controlled by other people communicate successfully with the processes that you control? The HTTP standard gives us shared semantics for our "self descriptive messages"; when you violate that standard, you lose interop with things that you don't directly control.
And that in turn means that you can't freely leverage the wide array of solutions that we already have in support of HTTP, because you've introduce this inconsistency in your case.
The appropriate HTTP method to use for what you are currently doing? POST
REST (aka Richardson Level 3) is the architectural style of the world wide web.
Your "everything is a message to a single resource" approach gives up many of the advantages that made the world wide web catastrophically successful.
The most obvious of these is caching. "Web scale" is possible in part because the standardized caching support greatly reduces the number of round trips we need to make. However, the grain of caching in HTTP is the resource -- everything keys off of the target-uri of a request. Thus, by having all information shared via a single target-uri, you lose fine grain caching control.
You also lose safe request semantics - with every message buried in a single method type, general purpose components can't distinguish between "effectively read only" messages and messages that request that the origin server modify its own resources. This in turn means that you lose pre-fetching, and automatic retry of safe requests when the network is unstable.
In all, you've taken a rather intelligent application protocol and crippled it, leaving yourself with a transport protocol.
That's not necessarily the wrong choice for your circumstances - SOAP is a thing, after all, and again, your service does seem to be working as is? which implies that you don't currently need the capabilities that you've given up.
It would make me a little bit suspicious, in the sense that if you don't need these things, why are you using HTTP rather than some messaging protocol?
Until now, I used to think the only difference between GET and POST is the format on data trasmission.
In other examples I have seen that in REST Api, the only command to send information is POST, while for getting information is GET...
But what if I want to use GET also for information sending? I have to send a number of dataset names to be processed (usually a short number...)... I don't understand why GET doesn't fits this operation. Or it's only a "semantic" reason?
EDIT: I don't want answer about the general differences between GET or POST... I need to know if GET should not be used to update info of the server IN ALL CASES, in particular regarding my specific case, or there are some exceptions.
I don't understand why GET doesn't fits this operation. Or it's only a "semantic" reason?
Yes, but semantics are the entire point.
One of the important constraints of the REST architectural style is that of a uniform interface; the idea that all components understand messages the same way. What that gives us is the ability to achieve useful work using general purpose components.
In HTTP (an application built within the constraints of this style), that means that we can use browsers, and caches, and reverse proxies, and server toolkits, and so forth, mixing and matching as we go. It all works, because all of these components understand that a request should be interpreted as described in RFC 7230, and that the request method token is "the primary source of request semantics", and so on.
The semantics of GET have been defined, and we all share in that definition. The wording of the definition has evolved somewhat from its earliest specifications, but the basic semantics have been constant: that GET is effectively read-only, and that the message body (of the request) is of no semantic interest.
If you want to use an HTTP method where the message body is semantically significant, then you need to either relax some of the constraints of GET (for instance, by using POST), choose a different standardized method that better fits your use case (see the IANA HTTP Method Registry), or by defining (and potentially standardizing) your own HTTP method.
The core problem with trying to define a payload for GET - while your bespoke client may know what to do, and your bespoke resource may know what to do, general-purpose intermediates are likely to do the wrong thing (like caching responses without capturing the information in the request body, or discarding the body as unnecessary).
Note that information that is encoded into the target-uri works just fine; HTML forms using the GET method and other variations of URI templates can be used to construct a target-uri from local information that the server can interpret (of course, the defacto limits on target-uri length are much shorter than the defacto limits on payload size; it's not a universal solution).
I apologise if there is an answer for this already. I found related questions (e.g. HTTP status code for a partial successful request) but not exactly the same.
I'm building an API that returns data that is aggregated from multiple sources. Sometimes, some critical part of the data is unavailable and the client has to be made aware and error data is included in the response.
Other than the severity of the missing field(s), the rest of the resource is valid and useful and could be regarded as a partial update (e.g. if you only had permissions to see part of a resource).
So far, the options are
return 200, consider it a partial resource, handle the error data fields in the application as you would with any other data
return 207 to emphasise it's not fully successfully, but 207 is not strictly HTTP.
return 500 and handle the successfully returned data in the application as you would on a 200
I'm partial to option 1 but I'm not fully convinced. Is there a clear way of handling this? Perhaps defining a specific content-type?
You are missing the point here because a 500 is indicative of a failure of the system or the chain of communication, and since data is returned then it must be assumed that the resource exists and is found. What the OP has indicated is a partial result, implying composite data pertaining to the resource. This is necessarilly outside of the scope of http, which has done its job via a successful 200, unless you have elected a contract under which partial data is erroneous and thus a 40x.
I am learning about SOAP. I see that some header elements have a "mustunderstand" attribute that can be set to true or false. But what does it mean to "understand" a soap message? To parse it without errors? I have found a few sites that don't really explain it.
Can somebody give me a rundown of what's going on?
In order to call a web service you need to respect it's contract. If a web service has <operationA> and <operationB> but you send <operationC> to it you will get an error (a fault in SOAP parlance).
The web service has operations <operationA> and <operationB> and knows what to do with the message when the message contains <operationA> or <operationB>. But it doesn't have <operationC> and doesn't know what to do with a message that contains <operationC> so it just returns an error. An incorrect body can't be ignored but headers on the other hand have no restrictions on what they are so you need a different mechanism in order to handle them properly.
Headers are used to extend the message by adding transaction support, authentication, routing, and so on and so forth. But these extensions are not defined in the SOAP specification, they are user defined. The specification just says that headers are used for that and also specifies how the message must be processed when headers are present. The mustUnderstand attribute is part of the "how the message should be processed".
A SOAP message travels from the originator to the ultimate destination, potentially by passing through a set of SOAP intermediaries along the message path. A header can be targeted for a specific node or for the final node (i.e. SOAP 1.1 actor attribute or SOAP 1.2 role attribute), and when that happens the node must do something with the header. This can be either to use it or to ignore it.
The mustUnderstand attribute indicates whether processing of the header is optional or mandatory. This basically translates to the node trying to find an appropriate handler that matches the header and proceed with processing the message in a manner consistent with its specification. If it can't find an appropriate handler it must return an error and stop further processing. If mustUnderstand is true/1 the node is not allowed to ignore it.
For example, imagine the header is for transaction semantics (i.e. the call must be performed within a transaction so that operations are performed in an atomic way, either all succeeding or all failing). If the processing node sees the transaction header it should start that transaction. Imagine what would happen if the node sees the header but does not know what it is so it decides to just ignore it and no transaction is started.
Later, some operations fail while other succeed and there is no transaction to rollback. So now your application is in an inconsistent state.
The SOAP mustUnderstand attribute allows for robust evolution. Elements tagged with the SOAP mustUnderstand attribute with a value of "1" MUST be presumed to somehow modify the semantics of their parent or peer elements. Tagging elements in this manner assures that this change in semantics will not be silently (and, presumably, erroneously) ignored by those who may not fully understand it.
http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383500
When you think about it, doesn't the REST paradigm of being resource-oriented boil down to being object-oriented (with constrained functionality, leveraging HTTP as much as possible)?
I'm not necessarily saying it's a bad thing, but rather that if they are essentially the same very similar then it becomes much easier to understand REST and the implications that such an architecture entails.
Update: Here are more specific details:
REST resources are equivalent to public classes. Private classes/resources are simply not exposed.
Resource state is equivalent to class public methods or fields. Private methods/fields/state is simply not exposed (this doesn't mean it's not there).
While it is certainly true that REST does not retain client-specific state across requests, it does retain resource state across all clients. Resources have state, the same way classes have state.
REST resources are are globally uniquely identified by a URI in the same way that server objects are globally uniquely identified by their database address, table name and primary key. Granted there isn't (yet) a URI to represent this, but you can easily construct one.
REST is similar to OO in that they both model the world as entities that accept messages (i.e., methods) but beyond that they're different.
Object orientation emphasizes encapsulation of state and opacity, using as many different methods necessary to operate on the state. REST is about transfer of (representation of) state and transparency. The number of methods used in REST is constrained and uniform across all resources. The closest to that in OOP is the ToString() method which is very roughly equivalent to an HTTP GET.
Object orientation is stateful--you refer to an object and can call methods on it while maintaining state within a session where the object is still in scope. REST is stateless--everything you want to do with a resource is specified in a single message and all you ever need to know regarding that message is sent back in a single response.
In object-orientation, there is no concept of universal object identity--objects either get identity from their memory address at any particular moment, a framework-specific UUID, or from a database key. In REST all resources are identified with a URI and don't need to be instantiated or disposed--they always exist in the cloud unless the server responds with a 404 Not Found or 410 Gone, in whch case you know there's no resource with that URI.
REST has guarantees of safety (e.g., a GET message won't change state) and idempotence (e.g., a PUT request sent multiple times has same effect as just one time). Although some guidelines for particular object-oriented technologies have something to say about how certain constructs affect state, there really isn't anything about object orientation that says anything about safety and idempotence.
I think there's a difference between saying a concept can be expressed in terms of objects and saying the concept is the same as object orientation.
OO offers a way to describe REST concepts. That doesn't mean REST itself implements OO.
You are right. Dan Connolly wrote an article about it in 1997. The Fielding thesis also talks about it.
Objects bundle state and function together. Resource-orientation is about explicitly modeling state(data), limiting function to predefined verbs with universal semantics (In the case of HTTP, GET/PUT/POST/DELETE), and leaving the rest of the processing to the client.
There is no equivalent for these concepts in the object-orientation world.
Only if your objects are DTOs (Data Transfer Objects) - since you can't really have behavior other than persistence.
Yes, your parallel to object-orientation is correct.
The thing is, most webservices (REST, RESTful, SOAP,..) can pass information in the form of objects, so that isn't what makes it different. SOAP tends to lead to fewer services with more methods. REST tends to lead to more services (1 per resource type) with a few calls each.
Yes, REST is about transfer of objects. But it isn't the whole object; just the object's current state. The implicit assumption is that the class definitions on both sides of the REST are potentially similar; otherwise the object state has been coerced into some new object.
REST only cares about 4 events in the life on an object, create (POST), retrieve (GET), update (PUT) and delete. They're significant events, but there's only these four.
An object can participate in lots of other events with lots of other objects. All the rest of this behavior is completely outside the REST approach.
There's a close relationship -- REST moves Objects -- but saying they're the same reduces your objects to passive collections of bits with no methods.
REST is not just about objects, its also about properties :: a post request to /users/john/phone_number with a new phone number is not adding a new object, its setting a property of the user object 'john'
This is not even the whole state of the object, but only a change to a small part of the state.
It's certainly not a 1:1 match.