Last week Software AG announced the Trial Version of Webmethods 10.1 had been released. I must admit I've been looking forward to this since the October release note promised they'd be significantly improving their Rest API and Swagger support, specifically:
REST enhancements: Integration Server and Designer now support the ability to read a Swagger specification and automatically generate a REST API descriptor. Additionally, there is support for REST v2 and the OAuth 2.0 Introspection specification. IS can now authorize OAuth2 tokens issued by third-party identity providers like Ping Identity and Okta.The ability to generate Swagger from a REST service in Webmethods has been around for a while - although it's been far from bug free. I was keen to see if this was resolved, but more importantly I prefer to develop "contract first" so the import capability is a big selling point for me.
This blog covers my first impressions - and sadly some of the issues I've already found after only a couple of hours experimenting with the tool.
The first thing I noticed is that the 10.1 installer package is much bigger than 10.0 (5.5GB vs 2.1GB). I don't know what extra they've crammed into the package to make it this much bigger but I certainly noticed that it took a while to download. Installation doesn't appear to have changed since 10, and it was fairly easy to get a clean local environment up and running.
I chose to import the petstore example from swagger.io and imported them into myImportedApi Rest API in a HelloWorld package. I wasn't sure what to expect but after a few seconds this appeared:
So far so good and to be honest I was pleasantly surprised.
- DocTypes: Webmethods "Documents" were created for all swagger data definitions
- Services: A flow had been created for each API, using the swagger label for the name of the flow service, and even including the swagger description in the flow service comments tab.
- Resources: Finally a resource was created for each tag in the Swagger file, and all the associated endpoints associated with them. Best of all, they maintained their url templates from the swagger (e.g. you call /v2/pet not /services/myImportedAPI/v2/pet as the folder naming would suggest). This is good as it means the generated services meet the contract as defined by the swagger. So far I was very impressed.
My first GET Service
First thing to try was a simple GET service. I selected the getPetByID flow - the inputs and outputs are already filled out which again saves time - all good:
So I simply wired the petId (from the URL e.g. GET /v2/pets/123) into the id in the output and set everything else to dummy values.
I imported the swagger file into postman and gave it a try:
Success! Everything comes back as a JSON object and is set correctly. So far this really is quite impressive in terms of accelerating development. As the swagger for this service promised a response in both XML and JSON, I switched the Accept header to "application/xml" and re-ran the service
Oh no! The XML certainly doesn't look the same as the JSON response, rather it looks like some horrible internal representation of the data in Webmethods - worse still it doesn't meet the contract promised by the Swagger definition. Just to show what should be there I switched the URL to point to petstore.swagger.io rather than localhost:
This is a fairly major impact if you're planning on using XML in your APIs (although I admit I tend to use JSON these days).
My first POST Service
As a final test I thought I'd try a POST service. For this I selected AddPet - to see what was going on I wrote a very simple Java service to log some of the input values using:
com.wm.util.JournalLogger.log(3,90,3,"LOG: Id=["+id+"] name=["+name_1+"]" );
I didn't "drop" any variables, so although though the Swagger spec didn't say anything will be returned Webmethods should just pass the input payload right back as a response.
Oh dear! This is even worse than the GET. There are a couple of things wrong here
- The format has changed between input and output with a new wrapper called "0" added
- The log is missing data: 2017-11-15 16:53:05 GMT [ISP.0090.0003I] LOG: Id=[null] name=[null]
It took me a little time to figure out why but then I added in a wrapper around the data (called fudge in this example):
This now the logging works correctly - but in both cases the output is different from the input. Without the fudge it adds an element, with the fudge it removes it. This has a couple of implications:
- If someone does a GET from the first service and then tries to PUT / POST the object into the new service it won't work without changing the JSON. This breaks the whole idea of REST you transfer the state of an object around. As such the object has to remain the same.
- The returned object isn't the same as the sent one. POST and PUT APIs occasionally use this as a confirmation check that things were written correctly (although HTTP status codes should prove this)
- Most importantly it doesn't match the swagger. This means that if the client is using the swagger to do validation of their request and the response one or other will always fail - and even if they're not the swagger documentation which is meant to explain how to use the API doesn't match reality.
On the one hand this is a bit easier to fudge around than the XML GET problem - although as a user of JSON it's personally more annoying.
Why this matters
Firstly it's a real pain for developers to not be able to rely on what the Swagger tells them - the whole point of having a contract is two fold: first documentation which is machine readable makes it automatically generatable/updatable meaning its more likely to be accurate; secondly you can mock/test against the swagger documentation when an integrated environment isn't available. But there's another bigger consideration.
If (or I hope when) Webmethods fix this bug then applying the fix will cause a breaking change in any APIs built before the fix. This means we need to work a fudge into our APIs now, and then potentially keep fudging them later (leading to an inconsistent set of APIs with some fudged and some not) or fudge them and upversion to the way we'd like it to work. If these are externally facing APIs with multiple external developers and/or mobile apps using them this causes a real headache.
Ultimately this means I'd be reticent to build APIs using this functionality, which is a shame because without these bugs it's actually really nice, and would be a real productivity saving over doing this all manually. I really hope Software AG get this patched soon.
Update 2017-11-20According to the Fixpack 1 release note, the JSON POST issue has been resolved - although I've not been able to test it using my trail account as I can't download the fix pack :(. I've not seen anything about the XML response issue yet.
Integration Server does not provide the expected response to a
REST request that contains JSON content.
When a REST client sends JSON content using the HTTP POST method
in its request to Integration Server, the received content is
modified internally because of which Integration Server does not
provide the expected response to the request.