Using Apiary.io, is it possible to POST requests to the same endpoint, which contains different content in the body, and return different HTTP 201 responses, based on the request body?
Only, we have an API that returns calculated data based on data it receives in the request. The data in the request is sent via POST because the amount of data can be too much for GET to cope with.
The following isn't an example of my data, but is an example of what I'm trying to achieve. A single endpoint, but two requests and two responses; so if the first request is sent, the first response should be returned, and if the second request is sent, the second response is returned.
## Example Collection [/example]
### Create a New Example [POST]
An example.
+ Request (application/json)
{
"ExampleId":"A9F4B93A-4C02-462A-87C5-CF1EAD732A46"
}
+ Response 201 (application/json)
+ Headers
Location: /example/1
+ Body
{
"result":"dkk4948djjdf8i49"
}
+ Request (application/json)
{
"ExampleId":"97E8DD35-5A30-47ED-B92D-80D110A3AD0B"
}
+ Response 201 (application/json)
+ Headers
Location: /example/2
+ Body
{
"result":"05ikflk30gdgg"
}
Unfortunately Apiary's Mock server isn't able to do that (yet).
As a workaround, you can use the Prefer to ask for a particular response, based on the returned status code.
Related
I am passing the request as in my feature file and i am trying to do assert from request to response.
I have tried must contains queries but i am not sure if i am doing it correct, could you please help.
**Background:**
* configure headers = read('classpath:merchantServiceheaders.js')
Given url MservUrl
And path '/spapis/rest/sp-ms-engine/sp/ms/v1/engine/scanandredact'
Scenario Outline: ACH Low Value Payment Rips Services Summary
]
}***
What i would like to do is assert what i have in my request to what i will get back in response.
Since i am passing subject in request the same subject should be present in response
Possible in 0.9.3: https://github.com/intuit/karate#scenario-outline-enhancements
First change the Examples: column header to data!
And request data
When method post
Then status 200
And match response contains data
In 0.9.2 and earlier, with the Examples: column header as data
* def data = <data>
And request data
When method post
Then status 200
And match response contains data
My current project API using this response on success:
if it's create -> it will send created object (201)
if it's update -> it will send updated object (200)
if it's delete -> it will send 204 response
Most of recommendation for example http://jsonapi.org/ never said about successful message to shown to user. I've followed their rules to keep returning object or 204 on success
What if I want to show to user alert "Successfully created" or "Successfully updated"?. Should the message come directly from server or client side (type it down or use some locales)?
You should review the RFC 7231, and it's description of 200 OK
The payload sent in a 200 response depends on the request method. For the methods defined by this specification, the intended meaning of the payload can be summarized as:
POST a representation of the status of, or results obtained from, the action;
PUT, DELETE a representation of the status of the action;
So yes, using the response body to present a representation of an alert to the user is fine.
For 201 Created, the same basic rule applies
The 201 response payload typically describes and links to the resource(s) created.
204 No Content is not similar, for the simple reason that "No Content" refers to the message body; 204 is one of the ways that you can indicate to the client (and intermediary components) that the 0 byte payload is not an error.
The 204 response allows a server to indicate that the action has been successfully applied to the target resource, while implying that the user agent does not need to traverse away from its current "document view" (if any). The server assumes that the user agent will provide some indication of the success to its user, in accord with its own interface, and apply any new or updated metadata in the response to its active representation.
I have an angular client which is making a POST call to my server. This server needs to get a response by calling another server(server2) with a POST call and pass the response from the server2 to the client. I tried the following approaches.
public Response call(){
String server2Url = "http://server2/path"
RestClient restClient = new RestClient();
return Response.fromResponse(restClient.post(server2Url)).build();
}
But in the above case the HTTP status code gets transferred but not the response body. The response body is empty
Then I tried:
public Response call() throws URISyntaxException{
String server2Url = "http://server2/path"
RestClient restClient = new RestClient();
return Response.temporaryRedirect(new URI(server2Url)).build();
}
but the browser client ends up making an OPTIONS call to the server2Url instead of a POST
and I tried.
public Response call() throws URISyntaxException{
String server2Url = "http://server2/path"
RestClient restClient = new RestClient();
return Response.seeOther(new URI(server2Url)).build();
}
but this ends up making a GET call instead of a POST.
How do I make the browser client make a POST call to server2
You can use Html Client from JAX-RS to make your own requests (from server1 to server2) and then return the response from server2 to the angular client.
public Response call() {
String url = "server2 url";
Response response;
try {
response = ClientBuilder
.newClient()
.target(url)
.request()
.post(Entity.json(null), Response.class);
}
catch (Exception e) {
// Whatever you want
return null; // or error
}
// Return the status returned by server 2
return Response.status(response.getStatus()).build();
}
What you are trying to accomplish is covered in the RFC 2616 I just found here.
If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.
So it looks like this is out of your hands if you´re not implementing the client.
Edit because I was told that RFC 2616 must not be used any longer.
RFC 7231 states that:
302 Found
The 302 (Found) status code indicates that the target resource
resides temporarily under a different URI. Since the redirection
might be altered on occasion, the client ought to continue to use the
effective request URI for future requests.
The server SHOULD generate a Location header field in the response
containing a URI reference for the different URI. The user agent MAY
use the Location field value for automatic redirection. The server's
response payload usually contains a short hypertext note with a
hyperlink to the different URI(s).
Note: For historical reasons, a user agent MAY change the request
method from POST to GET for the subsequent request. If this
behavior is undesired, the 307 (Temporary Redirect) status code
can be used instead.
What is:
307 Temporary Redirect
The 307 (Temporary Redirect) status code indicates that the target
resource resides temporarily under a different URI and the user agent
MUST NOT change the request method if it performs an automatic
redirection to that URI. Since the redirection can change over time,
the client ought to continue using the original effective request URI
for future requests.
The server SHOULD generate a Location header field in the response
containing a URI reference for the different URI. The user agent MAY
use the Location field value for automatic redirection. The server's
response payload usually contains a short hypertext note with a
hyperlink to the different URI(s).
Note: This status code is similar to 302 (Found), except that it
does not allow changing the request method from POST to GET. This
specification defines no equivalent counterpart for 301 (Moved
Permanently) ([RFC7238], however, defines the status code 308
(Permanent Redirect) for this purpose).
I have an HTTP JSON endpoint localhost:8000/resource/ that takes JSON data as input and returns JSON as output. I am now adding API Key based authorization to the endpoint. There are 2 ways to accept the API Key at this endpoint:
Method A: In the request headers
Example python code:
import requests
headers = {
'API-Key': '<my-api-key>',
}
r = requests.post('http://localhost:8000/resource/',
json={'input': <value>},
headers=headers)
Method B: In the JSON data itself
Example python code:
import requests
r = requests.post('http://localhost:8000/resource/',
json={'input': <value>, 'API-Key': '<my-api-key>'},)
I usually notice Method A being adopted. Is there anything wrong with latter approach in which the API key is passed along with the other json data?
I think it has to do with clarity, the API Key isn't really relevant to the input, it's just a form of authorization.
Large frameworks that deal with routing and such are able to filter based on specific headers, and it would be cumbersome to filter based off of a specific form of input in the request body that would require user to intervene and obtain that value for it. Headers are simpler, and suffice for simple data that would fit in a hash-table.
I want to pass some data within request body, but I'm using GET request, because I just want to modify this data and send it back.
I know that it is bad practice to use body with GET requests.
But what should I do with this situation if I want to build correct RESTful service?
P.S. I'm not changin any object on server.
I'm not putting any new object on server.
You want a POST. Something like
POST /hashes
{
"myInput": ...
}
The response would be the hashed value. There's no rule that the created resource must be retained by the server.
From the RFC:
The action performed by the POST method might not result in a
resource that can be identified by a URI. In this case, either 200
(OK) or 204 (No Content) is the appropriate response status,
depending on whether or not the response includes an entity that
describes the result.