I'm using swagger blocks with rails. I one of the enpoint I have an image upload.
parameter name: :tile_background_img,
in: :formData,
type: :file,
description: 'Tile background image'
On the swagger site it looks ok. If I add this image request has a header
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarybl70oGERlw1hSmnH and everything is fine.
When I use other params and leave image blank I got EOFError Bad request content body the header is
Content-Type: text/html
According to this answer https://stackoverflow.com/a/37932354 I should add consumes. However in the docs this option is only in the general api settings and it's not working for me https://github.com/fotinakis/swagger-blocks.
It turned out that I had to add in: :formData for other params in the request.
Related
I am facing fellow two problems related to Swagger open API
I am not able to pass custom header through swagger open API while calling my API, please suggest how can we pass custom header, through swagger open API.
When I added POI dependency on my project's pom.xml, it stopped working through swagger open API, however, it is working with the postman, please suggest what could be the issue.
From Describing Parameters:
An API call may require that custom headers be sent with an HTTP request. OpenAPI lets you define custom request headers as in: header parameters. For example, suppose, a call to GET /ping requires the X-Request-ID header:
GET /ping HTTP/1.1
Host: example.com
X-Request-ID: 77e1c83b-7bb0-437b-bc50-a7a58e5660ac
Using OpenAPI 3.0, you would define this operation as follows:
paths:
/ping:
get:
summary: Checks if the server is alive
parameters:
- in: header
name: X-Request-ID
schema:
type: string
format: uuid
required: true
My API consumes requests only with Header - Content-type:application/json object.
To do the same I use:
#OA\RequestBody(
description= "Provide company search parameter",
required= true,
#OA\JsonContent(
type="object",
#OA\Property(property="company_name", type="string")
)
)
But for some requests I don't need the RequestBody, only hit the resource and get data. How do I do it without RequestBody?
P.S. This request requires a GET method (POST can be used, if that helps) but GET doesn't accept a RequestBody.
This case cannot be described by OAS 3.0, and the restriction on GET requestBodies is to avoid attempting to describe API behaviour which the HTTP spec says is undefined. The restriction on specifying Content-Type as a 'manually' defined header is also to ensure there is no ambiguity as to which mechanism is supposed to set this header.
https://github.com/OAI/OpenAPI-Specification/issues/1628
When a client is sending the Content-Type header, it is used to describe the body of the request (not the response)
To influence the the response type a client can send an Accept header.
For example: Accept: application/json
I have an API call which responds 200 OK and returns an HTML. I would like to add this to my API documentation
(especially since i validate it using dredd and unless i provide it with the expected response body the test fails). How
would i do this in Swagger?
--- More details ---
My Response to an API call is 200 OK and with a one line Response Body:
<html><body>You are being redirected.</body></html>
I can easily define the Response Body in Blueprint in the following form:
+ Response 302 (text/html; charset=utf-8)
+ Body
`<html><body>You are being redirected.</body></html>`
But i'm not sure how to do this in Swagger. Almost all examples i can find are for application/json responses (understandably) and i'm having trouble
guessing the correct syntax for this kind of response.
The relevant swagger text in my document is this (so far without specifying the response body, so with an empty body dredd
fails because the response body should be <html><body>You are being redirected.</body></html>):
# this is my API spec in YAML
swagger: '2.0'
info:
title: My API (Swagger)
description: blablabla
version: "1.0.0"
# the domain of the service
host: my.domain.com
# array of all schemes that your API supports
schemes:
- https
# will be prefixed to all paths
basePath: /
produces:
- application/json; charset=utf-8
paths:
/users/password:
post:
summary: Password Reset
description: |
Handles Reset password for existing user.
consumes:
- application/x-www-form-urlencoded
produces:
- text/html; charset=utf-8
parameters:
- name: "user[email]"
description: email
in: formData
required: true
type: string
default: "user#gmail.com"
tags:
- Reset Password
responses:
200:
description: Success
Please comment if you have any suggestions on this. Thanks!
Figured it out. the response object has a field called "examples" which allows to show examples to your API response.
The syntax is clearly shown in the specification and basically says you need to identify the MIME-type for the example response, in my case text/html and the value is the actual text.
so like this:
responses:
200:
description: success and returns some html text
examples:
text/html:
<html><body>Your HTML text</body></html>
That's it. Now whether or not dredd knows to take this value and compare it is another story. their docs state that any response other than JSON is validated as plain text so this should work.
Hope this helped.
In case someone needs this in the openapi version 3.0 you can do it this way:
Save your HTML. For example give this at the end of your file:
components:
schemas:
error401:
type: string
example: '<html>HTML text</html>'
Then you can reference this scheme in responses wherever you want. For example:
responses:
'401':
description: Error
content:
text/html:
schema:
$ref: '#/components/schemas/error401'
The code: I got the following piece of code in some HAML file.
= image_tag "https://s3.amazonaws.com/my_bucket/my_image.jpg"
It sends a request to s3 and loads the image in the browser. I got the following CORS configuration on the bucket:
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>https://www.my_site.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>
The problerm:
In order to be able to manipulate the images on client side, the images are supposed to be served with the following headers:
Access-Control-Allow-Origin: https://www.my_site.com
Access-Control-Allow-Methods: GET
but this does not happen.
The cause: My browser does not send 'Origin' request header, and therefore s3 does not respond with the desired headers.
Why I think that missing "Origin" header is the cause:
Because the response of:
wget --server-response --header "Origin:https://www.my_site.com" "https://s3.amazonaws.com/my_bucket/my_image.jpg"
is the following:
HTTP/1.1 200 OK
x-amz-id-2: kQV8HEChV1...QHmHC1Gt/
x-amz-request-id: A626...4A2
Date: Wed, 03 Jul 2013 10:10:38 GMT
Access-Control-Allow-Origin: https://www.my_site.com
Access-Control-Allow-Methods: GET
Access-Control-Allow-Credentials: true
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
...
i.e. the 'Access-Control-Allow-Origin' and 'Access-Control-Allow-Methods' are present.
The supposed solution:
Is there a way to add manually the desired headers to the image_tag in the HAML file? Something like:
= image_tag "https://s3.amazonaws.com/my_bucket/my_image.jpg", :headers=>["Origin"]
Not using image_tag, no. Remember all image_tag does is generate the HTML tag. The end user's browser is responsible for loading the image source and displaying it. Unless I've missed something major, there isn't any way for you to tell the browser to pass additional headers via HTML.
You might be able to change your method and load those images using Javascript. Maybe you can pass headers that way.
Check How to debug CORS error for a solution.
I spent a lot of time thinking the problem was server side but finally it was due to a browser issue.
You can force Chrome to user the proper CORS protocol by loading your image through JavaScript.
Try changing your html to an empty img tag and loading your image into it. Like:
<span id="source-url" class="hidden"><%= #product.images.first.attachment.url(:large) %></span>
<img id="art-image">
and in a .js file
artImage = document.getElementById('art-image');
$(artImage).attr('crossOrigin', '');
$(artImage).attr("src", $("#source-url").text());
$(artImage).one('load', function() {
// image processing
});
Hope it helps!
I'm trying to implement an odata consumer, specifically right now related to doing batch operations and change sets, following the odata documentation essentially loads to this sample multipart batch that I've used as a basis.
However when I actually run this batch code (via fiddler request builder for example) updated with my own entity paths and such, I receive the following error:
Error processing batch request. At the
start of every operation, exactly two
headers need to be specified:
'Content-Type' and
'Content-Transfer-Encoding'. Make sure
these headers are present and have the
correct values.
If I remove the Content-ID from the change set the change set works correctly, but obviously the later operations no longer work because they reference this Content-ID.
I've attempted to move the Content-ID header out of the change request multipart.. part headers, and into the actual part payload request headers, ie:
--changeset(77162fcd-b8da-41ac-a9f8-9357efbbd621)
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1
POST /service.svc/Customers HTTP/1.1
Host: host
Content-Type: application/atom+xml;type=entry
Content-Length: ###
<AtomPub representation of a new Customer>
becomes
--changeset(77162fcd-b8da-41ac-a9f8-9357efbbd621)
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /service.svc/Customers HTTP/1.1
Host: host
Content-Type: application/atom+xml;type=entry
Content-Length: ###
Content-ID: 1
Again this no longer complains about the change set having only headers, but still the later reference the content id fails with
HTTP 404, Resource not found for the segment '$1'
The request part which references this content-id looks something like this:
--changeset_7448d3fc-39f6-49bb-b822-30fa4a1676ce
Content-Type: application/http
Content-Transfer-Encoding: binary
POST http://example.org/test.svc/$1/$links/Resources HTTP/1.1
Content-Type: application/json
.. json ..
Assume that http://example.org/test.svc is the service root.
The documentation isn't very clear really about the format of the inner request locations, so the path reference may be incorrect.
Hopefully somebody has better understood this aspect and can advise, thanks in advance.
Stephen.
Turns out you cannot refer to a change set request if the operation in this way if the operation isn't a POST, this makes sense from the aspect that only POST methods really require this reference, but it would be useful to not need this branching logic.
Importantly however the path when referencing the Content-ID should not be absolute, but instead simply:
POST $1/$links/Resources HTTP/1.1
Content-Type: application/json