We have SOAP services that are consumed by clients. We want to make changes to the service so that some of the existing fields that are currently char(20) we would like make them char(80). My understanding is that this is a compatible change and should not affect any existing SOAP Clients. Any thoughts ?
I would also assume that this will have no ill affects
Related
We have different client applications (each is built with a different UI and is targeted to a different sales channels) that are used to capture orders that ultimately need to be processed by our factory.
At first we decided to offer a single "order" microservice that would be used by all these client applications for business rules execution and data storage. This microservice will also trigger our backoffice processes such as client profile update, order analysis, documents storage to our electronic vault, invoicing, communications, etc.
The challenge we are facing is that these client applications are developed by teams that are external to ours (we are a backoffice team only). Each team responsible to develop a client application will be able to offer a different UX to their users (some will allow to save orders in an incomplete state, some wil allow to capture data using a specific worflow, some will use text fields instead of listboxes for some values, etc.).
This diversity of behaviors from client applications is an issue because our microservice logic will become very complex to be able to support all those UI requirements. Moreover, everytime a change will be made to one of the client applications, we will have to modify our microservice which is a case of strong coupling.
My questions are: What would be your best advice to manage this issue? Should we let each application capture the data the way it wants (and persist it if needed in its own database) and let them call our microservice only when an order is complete and compliant to our API contract?
Should we keep our idea of having a single "order" microservice for everyone and force each client application to capture the data the same way?
Any other option?
We want to reduce the duplication of data and business rules in our ecosystem but in the same time we don't want our 'order' microservice to become a mess.
Many thanks for your help.
Moreover, everytime a change will be made to one of the client applications, we will have to modify our microservice which is a case of strong coupling.
This rings alarm bells for me. A change to a UI shouldn't require a change to a backend service. (The exception would be if a new feature were being added to a system and the backend service needed to play a part in supporting that feature, but I wouldn't just call that a change to a client.) As you have said, it's strong coupling, and that's something to be avoided in a microservices environment.
Ideally, your service should provide a generic, programmatic API that is flexible enough to support multiple UIs (or other non-UI applications) without having any knowledge of how the UIs work.
It sounds like you have some decisions to make about what responsibilities your service will and won't take on:
Does it make more sense for your generic orders service to facilitate the storage/retrieval/completion of incomplete orders, or to force its clients to manage this somewhere else?
Does it make more sense for your generic service to provide facilities to assist in the tracking of workflows, or to force the UIs that need that functionality to find it elsewhere?
For clients that want to show list boxes, does it make sense for your generic orders service to provide APIs that aid in populating those boxes?
Should we let each application capture the data the way it wants (and persist it if needed in its own database) and let them call our microservice only when an order is complete and compliant to our API contract?
It really depends on whether you think that's the most sensible way for your service to behave. Something that will play into that will be how similar or dissimilar the needs of each UI is. If 4 out of 5 UIs have the same needs, it could well make sense to support that generically in your service. If every single UI behaves differently to the others, putting that functionality in your generic orders service would amount to storing frontend code somewhere that it doesn't belong.
It seems like there might also be some organisational considerations to these decisions. If the teams using your service are only frontend teams (i.e. without capacity/skills to build backend services), then someone will still have to build the backend functionality they require.
Should we keep our idea of having a single "order" microservice for everyone and force each client application to capture the data the same way?
Yes to the idea of having a single order service with a generic interface for everyone. With regards to forcing client applications to capture data a certain way, your API will only dictate what they need to do to create an order. You can't (and shouldn't) force anything on them about the way they capture the data before calling your service. They can do it however they like. The questions are really around whether your service supports various models of capture or pushes that responsibility back to the frontend.
What would be your best advice to manage this issue?
Collaborate with the teams that will use the service. Gather as much information as you can about the use cases in which they intend to use it. Discover what is common for the majority and choose what of that you will support. Create a semi-formal spec (e.g. well-documented Open API), share it with the client teams, ask for feedback, and iterate. For the parts of the UIs that aren't common across clients, strongly consider telling those teams they'll need to support those elements of their design themselves, especially if they represent significant work on your end.
I developed a REST API with Play 2.2.0. Some controllers expose GET methods, other expose POST methods with authentication etc...
I developed the client using Play as well but I have a problem. How can I avoid duplicating the model layer between both applications ?
In the server application, I have a Model Country(code, name).
In the client I am able to list countries and create new ones.
Currently, I have a class Country in both sides. When I get countries I deserialize them. The problem is that if I add a field in Country in the server, I have to maintain the client as well.
How can I share the Country entity between applications ?
PS : I don't want to create a dependency between the API and the client, as the client could have been developed with another language or framework
Thanks
This is not very specific to play framework but is more of a general question. You either create reusable representations of the data in your protocol (the actual data structures you send between your nodes) and get a tight coupling in representation and language. Many projects does it like this, since they know they will have the same platform throghout their architecture.
The other option is to duplicate all of or only the parts of parsing/generating that each part of the architecture needs, this way you get a looser coupling and can use any language in the different parts.
There are also some data protocols/tools that will have a representation in a protocol specific way and then can generate representations in various programming languages.
So as you see, it's all about pros and cons - neither solution is "the right way (tm)" to do this, you will have to think about your specific system/architecture and what pros are most valuable and what cons are most costly to you.
Well I suggest to send to the client a template of what they should display, on the client with js take advantage of js template frameworks, so you can tell to the client how can show them, dynamic... if they want to override them well... more job
We can call them Rest component oriented...
well suggestions :)
should works!
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to version REST URIs
I'm currently writing a REST service and I would like to get some ideas on how my clients can specify the service version when making a request.
For example when I upgrade my REST server to version 2 I don't want calls to break for all clients that have implemented version 1 of my service.
I've seen others add the version in the url or specify the version in the header somewhere.
There may not be a "best" way to implement this but I would appreciate some thoughts on the subject( pro's and con's of each etc...)
Thanks
We do it via separate routes:
http://my.service.com/v1/user/1
http://my.service.com/v2/user/1
In the case of no change between versions, we just map the route to the controller that services the v1 version of the resource.
Yes, this does create multiple URL's for the same resource, and the wonky hardcore REST evanginlists will start crying, but this way makes it easy to manage for you and your users. I find users can't even use request headers to set things like content types nevermind an X-Path or something like that to handle versioning....
If you really want to avoid the duplicate resource issue, you couldpass in a get paramter like version:
http://my.service.com/user/1?version=1
If no version, default to whatever. This is actually fully REST dogmatic, but I think it puts a lot onto your API users.
You could do some kind of user lookup table to route between version if you have a way to map user or api key to version, but this is pretty crazy overhead.
I would recommend versioning via the Accept/Content-Type header. The URIs shouldn't change across versions unless there is a large structural change to the resources themselves. Here is a great explanation: Best practices for API versioning?
I get the benefits of changing link uris, but that's really not what this question is about.
What I mean by evolvability is adding new features to a service or modifying (when possible) existing ones and that's actually it.
SOAP isn't that bad as REST community tends to talk about it when it comes to evolvability. For example:
In REST we can add new rel - in SOAP we can add new method. Both
types of old clients will continue working with new services.
In REST we can add new form field and set its default value - in
SOAP we could have service arguments as some ServiceArgs class and
add a new field to ServiceArgs. That's ugly, but it works.
What are the evolvability examples when SOAP clients break and you can do nothing about it, while REST clients are handling the situation gracefully?
Thanks!
SOAP is a contract-based technology. The entire client/server interaction is written up and codified in a big document (the WSDL) and must be agreed upon and honored by both sides in order for things to work. If either side decides to add features, the other side must "evolve" in lock-step with it. Both sides are completely coupled, joined at the hip, glued together, married, for ever.
The typical approach to enhancing your SOAP services is to create new WSDL documents for the new versions of the service, while also maintaining the older ones. Another technique is to create a new interface to contain new methods and inherit from the old one. The approach you describe in #1 is IMO breaking the SOAP rules, because the client and server will now be using different contracts and it only works because additive changes (like new methods) can be shoe-horned in and most of the time things will work. The moment someone makes a destructive change then the client's contract will not match the server's and it's game over. It's a difficult process to manage, which is why most organizations opt to create entirely new WSDL for each new version of the API.
REST doesn't magically make all of these problems go away, but it makes things easier to manage by not forcing you to bundle your entire distributed system's "contract" into one artifact. You're using HTTP? Great, then you get to use all of the wonderful HTTP features that the web uses too: proxy servers, URLs, content negotiation, authentication, etc. You want to communicate using JSON encoding as well as XML? Knock yourself out. It's trivial to do in REST at any time, without affecting existing clients. You want security? Fine, start challenging for authenticated credentials using HTTP's in-built support for exactly that. All of these things (HTTP, JSON, etc) are standardized and described in different places and that's exactly how it should be.
SOAP combines the transmission protocol, location information, payload description, encoding choice and RPC methods into one ginormous document. If you want to make any change to anything in that list, you need a new document. Worse still, some of those things can't be changed at all.
REST separates those things out so that the pieces can evolve independently. Your URLs (or "URIs", to be more precise) are returned at runtime and assuming the client doesn't start to hardcode them are evolvable without any changes needed to the client. Additive changes to your media types are trivial if your documentation makes it clear that new fields may appear in the future. You've also got the option of versioning your media types, allowing the co-existence of v1/v2/v3... media types within your system, and the client can pick (using the Accept and Content-Type headers in HTTP) which one they want to use.
Ever heard the joke about the Porsche owner who buys a brand new car whenever the ashtray gets full? That's SOAP. What should be a trivial change requires a major overhaul. REST gives you the vacuum cleaner. You don't have to use it, but it sure is cheaper.
I was wondering if it is possible to have a RESTful web service and a bidirectional communication with the clients and server.
In my case the state on the server can change, so the server should send a message to the clients to update themself. Perhaps that's totally against the RESTful idea.
Can I AJAX help me with this issue?
Thanks!
Not really possible under the standard http paradigm, but check out Comet for a possible workaround on that problem and there is alway polling.
The functionality you are after is treated by the concept of web sockets, but they are not mainstream yet.
To keep your solution RESTful you can have the clients poll your service. You can optimize any number of ways, like implementing a special method that lets clients query for changes given a timestamp, then the client just keeps track of when it last checked.
You should take a look at BOSH. BOSH is similar to Comet, but more specific, and I think, there are more reliable implementations.
Though, you will have problems serving multiple users at the same time if you want to use a standard REST service. You should think of some other implementation using nonblocking IO.
There are probably more questions about bosh. Of course, there are websockets now too, but if you need to serve old Browsers, you cannot rely on them.