API response with HTTP 200 with an XML body - ruby-on-rails

How can the HTTP 200 with an XML body be sent as the response of an API?
I am working on rails and the response of an API is in following format. It means like sending XML message:
<?xml version="1.0"?>
<s:Envelope>
<s:Body>
</s:Body>
</s:Envelope>
But I want to send HTTP 200 with an XML body instead of this XML Message.
Please suggest how can this be achieved?

In your controller method, do this if the request is successful
#some_response_object = Openstruct.new()
respond_to do |format|
format.xml { render xml: #some_response_object }
end
If you want to render a specific xml file, you simply use render, it'll try to find an xml file under the view folder which matches the file path.

Related

RESTClient not returning the Server Response Message

I am working on a ruby project which involve using RESTClient to reach out to an API. The API returns a 400 HTTP Status Code for a particular result with an accompanying response message (A JSON Response).
But when I check the response of my call:
response = RESTClient.post(...) {
logger.info response.to_s
}
I am getting a Proxy Server 400 page html:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>
which is not what I'm expecting.
Please what could be wrong?
Also, the behaviour is different with DEV and TEST Environment. On DEV Environment, it's giving the JSON while on TEST, I'm getting this issue.
Thanks.
If this is your API you can enable response in JSON format to any request. Just add this to your base API controller:
before_filter :default_request_format
private
def default_request_format
request.format = :json
end
If this is not your API you should specify Accept header with JSON content type.

using wslite in grails returning client - Internal Error

I have an xml that I am trying to send via wslite to my service. My service endpoint, lets call it https://development.net/InquiryService
Now when I send the following call through soapUI, I get the correct response
<soapenv:Envelope //my header information>
<soapenv:Header>
<wsec:Security>
<wsec:PartnerToken>
<wsec:PartnerId>xxxx</wsec:PartnerId>
<wsec:Password>yyyy</wsec:Password>
</wsec:PartnerToken>
</wsec:Security>
</soapenv:Header>
<soapenv:Body>
<acc:retrieveUserAccount>
<acc:SystemInfo>
<sys:ServiceContext>
<sys:transactionId>123</sys:transactionId>
<sys:sourceLogicalId>zzzz</sys:sourceLogicalId>
</sys:ServiceContext>
</acc:SystemInfo>
<acc:accessRegistration>
<acc1:userId>xxxx</acc1:userId>
</acc:accessRegistration>
</acc:retrieveUserAccount>
</soapenv:Body>
</soapenv:Envelope>
When I send the service request through grails, using
withSoap(serviceURL:"https://development.net/InquiryService"){
def response = send {
serviceRequest
}
}
I get wslite.soap.SOAPFaultException: env:Client - Internal Error
I have validated the xml is EXACTLY the same, so I'm not sure why this isn't working.
I think the issue is I need to add my wsdl somewhere, but where?
If the serviceRequest variable is a String, the following should work:
def response = send(serviceRequest)
The braces are causing it to pass a closure to send which if serviceRequest is a String you don't want to happen.

Rails not getting params from HTTP request

I'm trying to POST the following data to a Rails server (running on WebRick) from Android.
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<data>
<email>email.test#name.com</email>
<password>APassw0rd</password>
<remember_me>1</remember_me>
</data>
Now, the funny thing is that these data never show up in the params field in the controller.
Webrick does not output any parsing error. (And I guess it would post an error if it received a POST with no data attached:
Started POST "/users/sign_in.xml" for 192.168.1.94 at 2012-12-14 17:33:20 +0100
Processing by Users::SessionController#create as XML
Completed 500 Internal Server Error in 22643ms
I also found no trace of the data in the request.env variable. Actually, I see no HTTP_BODY in the dump fields. How can one see the raw body of the request? Would webrick really not complain if it received a POST with no attached data?
request.env would show the data as an IO object so you wouldn't be able to see your xml directly.
request.raw_post should return the raw data.
For rails to try and parse your xml into the params hash directly you need to set the content type of the request to application/xml. The 'processing as xml' stuff means that rails will try to render an xml response and doesn't necessarily have any bearing on the format of the posted data

rails 3 doesn't render format xml for string

so i'm trying to send xml back from my controller..
render xml: ['hello world']
correctly gives me:
<?xml version="1.0" encoding="UTF-8"?>
<strings type="array">
<string>hello world</string>
</strings>
however
render xml: 'hello world'
gives xml headers but the body is just:
hello world
which is not xml format.
bug?
From the API documentation:
When a request comes in, for example for an XML response, three steps
happen:
1) the responder searches for a template at people/index.xml;
2) if the template is not available, it will invoke
#to_xml on the given resource;
3) if the responder does not respond_to :to_xml, call
#to_format on it.
See: http://api.rubyonrails.org/classes/ActionController/Responder.html
In Rails, Arrays respond to to_xml but Strings do not.

How does rails determine incoming request format?

I'm just wondering how rails knows the format of the request as to correctly enter in the famous:
respond_to do |format|
format.html
format.xml
format.json
end
As an example consider this situation I have faced up. Suppose that via javascript (using jQuery) I make a POST request expliciting dataType: json
$.ajax({
type: 'POST',
url: 'example.com',
data: data,
dataType: 'json'
});
When this request reach controller action, standing inside it with ruby debugger, I inspect #request.format and I can see that content-type is application/json. Then the controller respond to json format as expected.
But I'm confused with the format symbol especified in the routes. Suppose that a request is made to example.com/parts.json but in the request the content type is application/html or application/xml. Is the controller responding to json format or html or xml??
Thanks!
From ActionController::MimeResponds: "Rails determines the desired response format from the HTTP Accept header submitted by the client."
The incoming Content-Type only affects the way the request is parsed. It doesn't affect the response format.
Since Rails 5.0, the response format is determined by checking for:
A format parameter (e.g. /url?format=xml)
The HTTP Accept header (e.g. Accept: application/json)
The path extension (e.g. /url.html)
You can see this in the implementation of ActionDispatch::Http::MimeNegotation#formats. Here is an excerpt from Rails v6.1:
if params_readable?
Array(Mime[parameters[:format]])
elsif use_accept_header && valid_accept_header
accepts
elsif extension_format = format_from_path_extension
[extension_format]
elsif xhr?
[Mime[:js]]
else
[Mime[:html]]
end

Resources