API requester generation using z/OS Connect build toolkit - zos

While we generate API requester artifacts using zconbt commandline tool and the API specification file the zconbt is not generating copybooks for multiple error responses. Suppose in the API swagger file we have defined response schema for HTTP codes 200, 400, 500 where the response schema definition is different for each of these responses. Now if we generate the copybooks using zconbt the zconbt ignores the response schema for 400 and 500 and generates the response copybook structure for 200 code only. Now when we invoke this API from MF and get a response with status code 400 and response message as per defined in the swagger for 400 then zcee is not able to transform and send the message back to the MF in a proper copybook variable. This is because the response schema for 400 was already ignored by zconbt in the first place.
So my question is do we have a work around to handle this type of scenario where we need to have all the error response schema available via cobol copybooks for handling the the error responses as well.

As you have said the API Requester functionality in z/OS Connect EE only provides JSON to COBOL transformation for the success case on an API call.
If the API call completes with something other than the success case, then the response information is returned as-is in the BAQ-RESPONSE-API structure.
Based on the example in the Knowledge Center you could process these responses as follows:
WHEN BAQ-ERROR-IN-API
EVALUATE BAQ-STATUS-CODE
WHEN 400
DISPLAY "Invalid Pet ID"
WHEN 500
DISPLAY "No pet found with ID "
WHEN OTHER
DISPLAY "API returned error "
BAQ-STATUS-CODE
END-EVALUATE
The JSON response is available in the BAQ-STATUS-MESSAGE field and could be parsed using the JSON support in COBOL or PL/I if required.

Related

Using JMeter, how to compare table data with JSON data?

I've got a task to compare all data fetched from postgreSQL table and all data located on a website that uses REST API (HTTP request with JSON data) in order to see which is missing.
I fetch data from postgreSQL using JDBC request (SELECT * FROM exampleTable), data is in standard SQL table format.
And I get REST API data using HTTP request sampler, data is in JSON format:
{"records":[{"id":"rec6iT8M0YFZc9kxf","fields":{"Birthday":"2010-09-01","Gender":"Female","Currently In Pasture":["rec7hRbjrgTaKWdCs"],"Breed":"Jersey","Weight":1800,"Name":"Jerri","Attachments":[{"id":"attbz","url":"https://IaGSYtK8SlS.jpg","filename":"Jersey_cow.jpg","size":1555316,"type":"image/jpeg","thumbnails":{"small":{"url":"https://_Jersey_cow.jpg","width":27,"height":36},"large":{"url":"https://dl/S4tl79.jpg","width":256,"height":341}}}]}
etc etc
both requests should have the same format of data (same "columns" for comparison > name, gender, breed, weight, etc)
I've tried using JSON Extractor post processor element to get individual variables from HTTP response and compare them to individual variables from JDBC request using the Response Assertion element but with no luck
I either get this error: Assertion failure message: java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.String (probably cause I am using the whole SQL data set instead of data from individual columns)
or something like:
Assertion failure message: Test failed: text expected to match /${gender}/
I dont know how to successfully assign variables to data from SQL table and JSON response and then matching those variable values (seeing which entries are absent from what REST API fetches)
is there any easy way to do this using jmeter GUI and not having to rely on beanshell/groovy or any other kind of scripting (so just by using the elements available in jmeter) ?
thank you!
Not knowing your database structure it is quite tricky to come up with exact solution, however you can convert JDBC Request output into a JSON using JSR223 PostProcessor
Example:
Given the following JDBC Request sampler configuration:
Which produces the following output:
I can convert it into JSON using the following Groovy code:
def result = vars.getObject('result')
def json = new groovy.json.JsonBuilder(result).toPrettyString()
log.info(json)
as you can see it contains column names along with the values, you should be able to use it for assertions.
More information: Debugging JDBC Sampler Results in JMeter

HTTP status while POST with incorrect data (using id of resource which does not exist)

What would be the correct HTTP status to return when I am performing the POST request to create a new user, but one of its parameters is incorrect - the company id I am including with the user data doesn't exist in the database.
POST
data: {username: 'newuser', age: 99, company_id: 34}
the company with id 34 does not exist in the database.
I was thinking whether that could be:
400, kind of invalid data, but it is valid but nonexistent id
404 - but it is not so clear which resource does not exist
409, because it is kind of conflict and the user can resolve that by changing the company id
422?
or 500 - because it is kind of database error while non existing id's are not allowed there
400 or 422
First of all, keep in min that it's a client error, so 5xx status codes are not suitable here. You should pick a 4xx status code then.
The most obvious options are 400 and 422:
If the JSON is syntactically invalid, return 400.
If JSON is syntactically valid but its content is invalid, return 422 to indicate that the request entity cannot be processed by the server.
See the following quote from the RFC 4918 (for your situation, just read JSON when it says XML):
11.2. 422 Unprocessable Entity
The 422 (Unprocessable Entity) status code means the server
understands the content type of the request entity (hence a
415 (Unsupported Media Type) status code is inappropriate), and the
syntax of the request entity is correct (thus a 400 (Bad Request)
status code is inappropriate) but was unable to process the contained
instructions. For example, this error condition may occur if an XML
request body contains well-formed (i.e., syntactically correct), but
semantically erroneous, XML instructions.
A similar situation was addressed in this answer.
For example purposes, the GitHub API v3 also returns 422 if the content of the payload contains invalid values (but is syntactically valid):
There are three possible types of client errors on API calls that
receive request bodies:
Sending invalid JSON will result in a 400 Bad Request response. [...]
Sending the wrong type of JSON values will result in a 400 Bad Request response. [...]
Sending invalid fields will result in a 422 Unprocessable Entity response. [...]
Michael Kropat put together a set of diagrams that's pretty insightful when it comes to picking the most suitable status code. See the following diagram for 4xx status codes:
404 Not Found is a problematic status to return for a POST request. It implies the resource you are sending the request to doesn't exist; the caller got the URL wrong.
The most obvious (and generic) answer is: 400 Bad Request
This just indicates there is something wrong with your request (the fault lies with the caller not the server) and then express the specific detail of what went wrong in your response body. This is typically how request validation is handled.
The ideal answer is to make it so you add a user by sending a request to the company they are a member of:
POST /company/34
Content-Type: application/json
{
"username": "newuser",
"age": 99
}
This means the caller has to find a valid company resource to send the request to. If company/34 doesn't exist, a 404 Not Found response is appropriate; you tried adding a user to a company which does not exist.
This does mean your API has to be structured with resource semantics and a user has to belong to exactly one company.
Here, this picture is very good, and I've used it many times.
Which code should I return?
I'd go with 404. The resource could exist (not a format error) but it just doesn't (and hence can't be found).

REST-API HTTP status code for invalid input on a Patch request

There is a Patch request on my application that updates a user's password. We have an Ember validator to block all invalid input except for 1 business rule, which is it should not be a password used as one of your past 5 passwords.
We are currently returning a 400 Bad Request in this case, however my company has a dashboard for component availability and counts 400 and 500 requests as unavailability, because most applications are SOAP and they just expect 200 and 300s. Even though we handle this 400 appropriately through the UI it is still a ding against us. And puts us on the radar as an area with poor availability.
Should we take this to the people that monitor availability and have them change this for REST services as this will become a more common and common occurrence as the company creates more REST applications. Or do we cave and return a 200 that also states that the password was not successfully updated?
I would argue that a 400 response is inappropriate for the service. If the service is responding with a 400 when the user's password has been repeated within the last 5 passwords, then the request was understood by the server.
According to the W3C:
The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without
modifications.
In your case, the request was understood. It is returning a 400 to signal an application concern (regarding password reuse). I believe a 200 response would be more appropriate with a payload indicating the application problem.
EDIT:
One might also argue that a 422 response would be in order:
The 422 (Unprocessable Entity) status code means the server
understands the content type of the request entity (hence a
415(Unsupported Media Type) status code is inappropriate), and the
syntax of the request entity is correct (thus a 400 (Bad Request)
status code is inappropriate) but was unable to process the contained
instructions. For example, this error condition may occur if an XML
request body contains well-formed (i.e., syntactically correct), but
semantically erroneous, XML instructions.

REST API: how to notify a client that the request has failed when the service already returned 200 and some data?

REST API: how to notify a client that the request has failed when the service already returned 200 and some data?
What I am doing?
I am developing a REST Web service that returns data from two sources:
An CSV file from an HTTP server which changes often and sometimes is huge.
A local file.
When a client invokes the service, it does this:
It sends a request to the HTTP server to obtain the CSV file.
After obtaining the CSV file, it combines the data from both sources.
Sends the result to the client. The result is an XML document.
Problem
Sometimes, after I have already returned some data to the client, the HTTP server fails so I cannot continue sending data to the client.
When this happens, I would like to notify the client that there was an error. How should I do this? The service already returned the HTTP code 200 and some data. So I cannot send the client an error 500.
Should I simply write to the output an error message? The client will fail because it the XML-document will not be valid.
The service cannot wait to send the response until the entire file from the HTTP server is read. The reasons is that sometimes the file obtained from the HTTP is very big and does not fit in memory.
Environment: although I do not think this is important, this service is developed in Jersey 1.x.
As you say, there are a couple options:
Start sending the response 200 OK before your upload request is complete, but rely on the client to detect an invalid ontent response; or
Wait until your request file upload is complete before sending the HTTP response. Then you can send the correct status code (2xx or 500).
I would recommend waiting until the upload is complete.
If the file cannot fit in server-side memory, then find a technique to write the stream to persistence not in memory, such as a cache, nosql db, or the filesystem. This will allow for faster processing of the file upload.
If you require additional time to process the file on the server side after upload, you can return a 202 Accepted status, with the Location: header having the resource to the long-running job. The client can keep checking if the job is complete. This will avoid having to process the whole thing in one HTTP round-trip.
some good examples of using RESTful long-operations:
Best practice for implementing long-running searches with REST
http://billhiggins.us/blog/2011/04/27/resty-long-ops/
REST with JAX-RS - Handling long running operations
Replying to myself. This may be useful for someone else.
Initially, I developed this option: if there was an error generating the output of the service when the HTTP code 200 was already sent, the service would write the error message to the output and close the connection. In these cases, the XML of the response was invalid.
Later, I had to change this behavior because users complained that in this scenario, the response was an invalid XML. As a consequence, all they were seeing was the error returned by the XML parser of their applications saying that the XML was invalid, not the actual error message.
To avoid this issue, I changed the behavior of the service:
When there are no errors, the response looks like this:
<view name="demo_stats">
<demo_stats>
<int_type>1</int_type>
<numeric_type>1.1</numeric_type>
</demo_stats>
<demo_stats>
<int_type>2</int_type>
<numeric_type>2.2</numeric_type>
</demo_stats>
</view>
If there is an error generating the output of the service and the service already sent the HTTP code 200, the response looks like this:
<view name="demo_stats">
<demo_stats>
<int_type>1</int_type>
<numeric_type>1.1</numeric_type>
</demo_stats>
<demo_stats>
<int_type>2</int_type>
<numeric_type>2.2</numeric_type>
</demo_stats>
<errors>
<error>There was an error transforming the value of row #3</error>
</errors>
</view>
The element errors is optional and only appears when there is an error during the generation of the output. This is a valid XML document and it allows client application to control better for this situation.

postman usage - how to input parameters

My rest service method demands an input parameter. I want to see data structure via postman. How can I add arguments in postman app? I get the error:
HTTP Status 500 - The bean encountered a non-application exception;
nested exception is: The server encountered an internal error that
prevented it from fulfilling this request.
Suppose that you are doing a POST, or a PUT, you want to add your data in XML or JSON or plaintext to the request.
You need to set the URL, and the right HTTP method. Once you choose, suppose POST, you can edit the data to be sent. I choose the raw input type and write inside it what I want to send to the server.
You may get 500 as server error due to error in the logic of the offered service, try to encapsulate your entity and send agin the request..