I am getting false in API query with code 200 with ruby - ruby

Friends, I can't understand what's going on, I'm new to programming.
#Create Employee
#manter_user = Crud.new (my class)
#Create
$response = #manter_user.create(my method)
puts "Response is: #{$response}"
puts "Create Response HTTP code 200: #{$response.code == 200}"
end
crete ok
Response is: {"status":"success","data":{"name":"Kip","salary":8037.4700000000002546585164964199066162109375,"age":63,"id":7435},"message":"Successfully! Record has been added."}
**Create Response HTTP code 200: true**
#list
#id = $response.parsed_response["data"]["id"]
puts "#id: #{#id} retornado é o mesmo préviamente criado..."
retrieve_response = #manter_user.retrieve(#id)
puts "Retrieve Response HTTP code 200: #{retrieve_response.code == 200}"
end
List
**Retrieve Response HTTP code 200: false**

As I mentioned in my previous Answer and the comments below.
The dummy API you are using does not actually store the records you are creating it just provides a dummy response.
These are fake online REST APIs for testing and prototyping sample applications that use rest calls to display listings and crud features. This rest api tutorials, faking a server, and sharing code examples can all be used.
Methods provided by the API:
Create - You can "create" a record and receive a fictional response but the record is not persisted.
{"status":"success","data":{"name":"Alva","salary":12,"age":33,"id":1488},"message":"Successfully! Record has been added."}
Retrieve an individual record - You can retrieve a single record up to id 24 (a fixed list of records are available). Response differs from other methods. (This will result in a failure of verifying a 200 HTTP status code if you use an id > 24, which would be the case if you are using the id from the previously created record (also see below for another reason))
{"status"=>"success", "data"=>{"id"=>9, "employee_name"=>"Colleen Hurst", "employee_salary"=>205500, "employee_age"=>39, "profile_image"=>""}, "message"=>"Successfully! Record has been fetched."}
Update - You can "update" a record with any id and receive a fictional response but the response is malformed JSON making it effectively useless.
{"status"=>"success", "data"=>{"{\"name\":\"Cassia\",\"salary\":\"100000\",\"age\":\"24\"}"=>nil}, "message"=>"Successfully! Record has been updated."}
Delete - You can "delete" a record with any id and receive a fictional response.
{"status"=>"success", "data"=>"78", "message"=>"Successfully! Record has been deleted"}
There is no way using this dummy API that you can actually test the full lifecycle of record due to the way it is constructed.
Additionally it appears this API is in the process of being torn down:
They are trying to sell the domain and associated code
The page regularly shows that it is down, suspended, or under maintenance
They recently have implemented request throttling which is now resulting in a HTML response of "Too Many Requests" which will make it more difficult to use for basic testing. (This will also result in a failure if verifying a 200 HTTP code response)

Related

Is there a way to get response on error with HTTPClient in Ruby?

I'm using the HTTPClient ruby library for making some basic http requests to a REST service I have develop and im wondering now how can I get the response from the service when an error occurred (a status code like 400 or 500 is returned from the service).
What my service does is return the stock of a product in a center, so it takes two parameters (in the url): a product id and a center id. When I call this service passing correct product and center ids the service returns me a 200 - OK status and the stock of the product (for example, 8.0 indicating there are 8 units of the product in that center). However, if I pass a wrong product id (one that is not in our database) the service returns 400 - Bad Request and an error message indicating that the id does not exists.
So I have a method like the following in Ruby
def stock(product, location)
response = #client.get_content("stock/#{product}/#{location}")
end
#client is an instance created with HTTPClient.new that I have configured. On passing ''right'' arguments it returns me what I want so it is well configured
My problem now is that when the service returns an error status code an HTTPClient::BadResponseError exception is thrown and I'm not able to retrieve this error in the response variable.
Is there a way to get the response from the service, no matter which status code it returns? I tried using begin...rescue and I can get some information like the status code and the reason phrase, but not the content of the response (the error message)
You're using get_content which skips a few steps and returns the content. Instead step back and use get which will return a more complete response structure that includes, among other things, the status field you want:
def stock(product, location)
response = #client.get("stock/#{product}/#{location}")
body = response.body
status = response.status
end

Have Dynamical values for my parameters in the Request payload (POST x-www-form-urlencoded)

Is there a way (and does it make sense even) to have dynamical values for my request parameters (in my case POST application/x-www-form-urlencoded that has two parameters username and password) which can be altered based on some function or a returned value from the server from a previous request?
The motivation being that i have a register-new-user request which i run from time to time off apiary.io and unless i manually change the example value for the username i get a "use already exists" response instead of 201 i want (since this request was already run with the username in the example).
What i'd like to have instead is a value in the API documentation that will change on each execution of the API call (either using some random number there, or to be able to have it take a value returned from a previous request).
Is there anything you can suggest to solve my "user already exists" response for register-new-user API call?
Here is my current API documentation (the relevant part):
## Registration [/users.json]
The `/users.json` resource handles registration of new user
### Register a New Patient [POST]
Register a new patient action sends email and password and registers
the new user in case it doesn't already exist
+ Request (application/x-www-form-urlencoded)
+ Attributes (Test User)
+ Body
user[email]=username#example.com&user[password]=123456
+ Response 201 (application/json)
{
"id":500
}
# Data Structures
## Test User (object)
+ "user[email]" (string): "username#example.com" - user email
+ "user[password]" (string): "123456" - user password
Thanks in advance
You can partially simulate this in the Apiary mock server by passing a header in your call, for example:
Prefer: status=200
See https://help.apiary.io/tools/mock-server/#multiple-responses
In general the mock server is not yet flexible and programmable enough to fully do what you describe, for example conditionals, dynamic variables or random responses.
We are working on enhancing this. If you'd like you may comment here on your requirements:
https://github.com/apiaryio/api-blueprint/issues/58
Feel free to also ping us in Apiary (in-app chat) or on support#apiary.io.
Thanks

Beanshell code to call an API, parse JSON response

I am trying to implement a logic where i do not want to send HTTP Requests unless an API returns 0 for a field. If i send the requests without monitoring response from this API, my test is invalid. API returns response in JSON, i can parse and extract the data i need to compare. Below is my test structure.
Thread Group
* While Controller
* CSV Data Set Config
* HTTP Request
* JSON Path Extractor
* Constant Throughput Timer
* While Controller Condition: ${__BeanShell(source("function.bsh”))} != “0”
I want to call this API after every 5 minutes and proceed with sending HTTP Requests when field value is 0. I don't want to check before every HTTP Request just once before sending the first request.
Can someone please help me with the beanshell code (function.bsh) to get API response and parse json response ? Was implemented using python as below
max_behind = 0
response = requests.get("https://api")
consumers = response.json().get("consumers")
for total_behind in consumers.iteritems():
max_behind += total_behind[1].get("total_behind")
As Jmeter developers suggested "Better to avoid scripting languages in Jmeter". So in your case use "If Controller" to resolve your blocker. Below are the details
Use regular expression to extract the "API return field" value, once you hold this value in a variable "valueIs". As shown in belo image
Use "If controller " and in condition enter the following value "${valueIs}==1", then add child requests ( next API call/calls) to "If controller". As shown below image

wireload / Ratatosk : How to make POST requests?

In my Cappuccino frontend I'm using Ratatosk to make queries to a RESTful JSON-based API.
When I create a new resource with
[myNewResource ensureCreated];
my backend returns the status code 201 and a Location header with the URI of the newly created resource. The response body is empty. As far as I know, that's the way a REST API should react to successful POST requests.
But upon receiving the response, Ratatosk calls
- (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)data
(in WLRemoteLink.j) and tries to decode the response body. This throws an error because the response body is empty. As a consequence, the request is repeated infinitely.
How should I go about this? Am I supposed to return the whole resource in the response body?
EDIT:
Returning the ID in the response solved the problem, like
{"id":1}
Ratatosk expects the status code 204 (no content) if the response is to be empty. Otherwise it expects the full representation of the resource which was just created (which it uses to populate server side dynamic properties locally like created_at).

To 406 or not to 406 (http status code)

I'm developing a RESTful web application in Ruby with Sinatra. It should support CRUD operations, and to respond to Read requests I have the following function that formats the data according to what the request specified:
def handleResponse(data, haml_path, haml_locals)
case true
when request.accept.include?("application/json") #JSON requested
return data.to_json
when request.accept.include?("text/html") #HTML requested
return haml(haml_path.to_sym, :locals => haml_locals, :layout => !request.xhr?)
else # Unknown/unsupported type requested
return 406 # Not acceptable
end
end
Only I don't know what is best to do in the else statement. The main problem is that browsers and jQuery AJAX will accept */*, so technically a 406 error is not really the best idea. But: what do I send? I could do data.to_s which is meaningless. I could send what HAML returns, but they didn't ask for text/html and I would rather notify them of that somehow.
Secondly, supposing the 406 code is the right way to go, how do I format the response to be valid according to the W3 spec?
Unless it was a HEAD request, the response SHOULD include an entity containing a list of available entity characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. Depending upon the format and the capabilities of the user agent, selection of the most appropriate choice MAY be performed automatically. However, this specification does not define any standard for such automatic selection.
It looks like you're trying to do a clearing-house method for all the data types you could return, but that can be confusing for the user of the API. Instead, they should know that a particular URL will always return the same data type.
For my in-house REST APIs, I create certain URLs that return HTML for documentation, and others that return JSON for data. If the user crosses the streams, they'll do it during their development phase and they'll get some data they didn't expect and will fix it.
If I had to use something like you're writing, and they can't handle 'application/json' and can't handle 'text/html', I'd return 'text/plain' and send data.to_s and let them sort out the mess. JSON and HTML are pretty well established standards now.
Here's the doc for Setting Sinatra response headers.

Resources