symfonyv3 & FOSRestBundlev2.1.1 : how to activate jsonp handling - jsonp

I've got this config.yml :
fos_rest:
routing_loader:
default_format: json
view:
mime_types:
jsonp: ['application/javascript']
formats:
jsonp: true
jsonp_handler:
callback_param: callback
mime_type: application/javascript
When I call example.com/app_dev.php/api/users/1.jsonp?callback=toto, I've got this reponse in plain HTML :
No route found for "GET /api/users/1.jsonp"
When I change my config file to :
fos_rest:
routing_loader:
default_format: json
view:
mime_types:
jsonp: ['application/javascript']
formats:
jsonp: true
jsonp_handler:
callback_param: callback
mime_type: application/javascript
format_listener:
rules:
- { path: '^/api', priorities: ['jsonp','json', 'xml', 'html'], fallback_format: json, prefer_extension: true }
the error is still the same, but json encoded.
If I modify application/javascript into application/javascript+json, chrome can't show the result
PS : everything work with the standards formats : html, xml, json

This link shows a simpler configuration:
http://symfony.com/doc/current/bundles/FOSRestBundle/2-the-view-layer.html#jsonp-custom-handler
So try:
# app/config/config.yml
fos_rest:
view:
jsonp_handler: ~
And see if that works.

Related

Swagger yaml (openapi-3.0) upload files does not work

I am using openapi 3.0 to write the swagger yaml file. But upload files feature doesnot work. the swagger ui does not display the upload button as expected. below is my swagger yaml code snippet. Can someone help to take a look? Thanks!!!
/uploadfiles:
post:
requestBody:
content:
multipart/form-data:
schema:
required:
- file_list
- statement_terminator
properties:
statement_terminator:
type: string
default_schema:
type: string
encoding_type:
type: string
file_list:
type: array
items:
type: string
format: binary
required: true
Add type: object to your multipart body schema:
multipart/form-data:
schema:
type: object # <------
required:
- ...

IBM Mobile First 7.1: multipart/related Content-Type and XSL transformation

I need to invoke from an HTTP adapter a SOAP service that has a multipart/related content type.
If I use this object as WL.Server.invokeHttp parameter
{
method : 'post',
returnedContentType : 'xml',
returnedContentEncoding : 'utf-8',
path : servicePath,
body : {
content : MY_REQUEST,
contentType : "text/xml; charset=utf-8"
},
transformation: {
type: 'xslFile',
xslFile: 'myXsl.xsl'
}
};
I got this error:
"Runtime: Failed to read the HTTP response to: /MyService
\njava.lang.IllegalArgumentException: Http content type 'multipart/related' not supported.
Supported types are: [json, css, csv, javascript, plain, xml, html]"
So I modified the parameter returnedContentType: 'plain' to obtain a result. Now the response looks like this:
{
"isSuccessful": true,
"errors": [],
"warnings": [],
"info": [],
"text": "--uuid:85c87f37-9436-41d1-94d4-0b944c3618b1\nContent-Type: application/xop+xml; charset=UTF-8; type=\"text/xml\";\nContent-Transfer-Encoding: binary\nContent-ID: <root.message#cxf.apache.org>\n\n
MY SOAP RESPONSE
\n--uuid:85c87f37-9436-41d1-94d4-0b944c3618b1--",
"responseHeaders": {
...
"Content-Type": "multipart/related; type=\"application/xop+xml\"; boundary=\"uuid:85c87f37-9436-41d1-94d4-0b944c3618b1\"; start=\"<root.message#cxf.apache.org>\"; start-info=\"text/xml\""
...
}
}
But the xsl transformation is not performed.
With some string manipulation on the text parameter I can obtain the SOAP response as a string but I didn't find a way(some API) to manually invoke the XSL transformation to obtain a json.
XSL transformation is done only on the server-side (there is no manual 'activation' for it). What you could do perhaps, if you still need to do XSL transformation, is run the XSL via JavaScript. See for example: how to run XSL file using JavaScript / HTML file

RAML : How to require parameter A OR parameter B

I'm writing some REST documentation with RAML but I'm stuck.
My problem:
- I have a GET request used for search that can take a parameter "id" or (exclusive or) "reference". Having only one of them is required.
I know how to say "this param is required" but I don't know how to say "having one of these params is required". Is it even possible?
The following example written in RAML 1.0 defines two object types in Url and File then creates another object Item which requires Url OR File in ext. If you change the included examples (which currently validate), you'll see that they fail if the property does not conform to one or the other definition. Hope that helps! LMK if you have any other questions and I'll do my best.
[EDIT: hmm I think I am seeing your problem now, the final example I've just added, named should_fail, (which has one of each type together in the example) still validates and you want a way to make it fail validation.]
[UPDATE: OK I figured a mildly hacky way to do this. Use maxProperties: 1 in the object which should have properties appear alone, see updated code below which fails the final example during validation.]
#%RAML 1.0
types:
Url:
properties:
url:
type: string
example: http://www.cats.com/kittens.jpg
description: |
The url to ingest.
File:
properties:
filename:
type: string
example: kittens.jpg
description: |
Name of the file that will be uploaded.
Item:
description: |
An example of a allowing multiple types yet requiring
one AND ONLY one of two possible types using RAML 1.0
properties:
ext:
maxProperties: 1
type: File | Url
examples:
file_example:
content:
ext:
filename: video.mp4
url_example:
content:
ext:
url: http://heres.a.url.com/asset.jpg
should_fail:
content:
ext:
url: http://heres.a.url.com/asset.jpg
filename: video.mp4
I had the same problem. User can provide either a textual input OR a file input, but not both.
Both have different fields and I detect the request type from the field names. i.e if the request has [files and parameters], it is a FileInput. If the request has [texts and parameters], it is a TextInput. It is not allowed to provide both text and file within the same request.
I used the union property. See CatAndDog example in
Raml 200 documentation for a small example.
You can define your types as follows.
types:
FileInput:
properties:
parameters:
type: Parameters
description: (...)
files:
type: ArchiveCollection | FileCollection
description: (...)
TextInput:
properties:
parameters:
type: Parameters
description: (...)
texts:
type: TextCollection
description: (...)
Then in my POST request body:
/your_route:
post:
body:
multipart/form-data:
type: TextInput | FileInput
The fields in the body are defined with either TextInput or FileInput type.
In RAML 0.8 you can not describe queryParameters with only one parameter.
In RAML 1.0 you can do this. You should use oneOf in jsonschema for describing Type. Your queryParameters should use this type. Example:
api.raml
#%RAML 1.0
title: AUTH microservice
mediaType: application/json
protocols: [HTTPS]
types:
- example: !include schemas/example.json
/example:
get:
queryParameters:
type: example
schemas/example.json
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"id": "file://schemas/credentials.json",
"oneOf": [
{
"properties": {"key1": {"type": "string"}},
"additionalProperties": false
},
{
"properties": {"key2": {"type": "string"}},
"additionalProperties": false
}
]
}
Also you can use uriParameters. Maybe it will help in your case.
#%RAML 0.8
title: API Using media type in the URL
version: v1
/users{mediaTypeExtension}:
uriParameters:
mediaTypeExtension:
enum: [ .json, .xml ]
description: Use .json to specify application/json or .xml to specify text/xml

How should I handle an application/javascript response type in Swagger?

I have a swagger app that works when JSON is returned, but not with JSONP. Success and fail cases are described further down.
It is worth noting that the exact controller code shown below works fine under vanilla node/express - the problem seems to occure when the response goes through the swagger response validator.
The snippet of controller code that handles the response is as follows:
retVal.success = true;
retVal.data = jsondata;
res.set('Content-Type', 'application/javascript');
res.jsonp(200, retVal);
swagger.yaml:
swagger: "2.0"
info:
title: sometitle
version: v1
host: localhost:3000
basePath: /
schemes:
- http
consumes:
- application/json
- application/javascript
produces:
- application/json
- application/javascript
- text/javascript
paths:
/loadallrepos:
x-swagger-router-controller: loadallrepos
get:
summary: summary here...
description: |
description here...
operationId: loadallrepos
parameters:
- name: callback
in: query
description: Passed by .ajax call for cross-domain requests
required: false
type: string
responses:
200:
description: Success
schema:
$ref: "#/definitions/loadallreposResponse"
definitions:
loadallreposResponse:
type: object
required:
- success
- data
properties:
success:
type: boolean
data:
type: object
required:
- nextrefresh
properties:
nextrefresh:
type: integer
If I make a request without the callback parameter, it works:
request: localhost:3000/loadallrepos
response:
{
"success": true,
"data": {
"nextrefresh": 3439704
}
}
If I turn it into a jsonp request though, it fails:
request: localhost:3000/loadallrepos?callback=jQuery111106460774131119251_1439402109118&_1439402109119
response:
{
"message": "Response validation failed: value expected to be an array/object but is not",
"failedValidation": true,
"originalResponse": "typeof jQuery111106460774131119251_1439402109118 === 'function' && jQuery111106460774131119251_1439402109118({
"success": true,
"data": {
"nextrefresh": 3442750
}
});"
}
Again, this works under vanilla node/express. Any help is greatly appreciated!
JSONP APIs return a string of JavaScript. Your Swagger definition says your API returns an object defined at #/definitions/loadallreposResponse which is of type object. What happens is swagger-node/swagger-tools sees a type of object and attempts to use JSON.parse on the response body and fails. To support JSONP with Swagger, you need to make your response schema be of type string to avoid response validation failure.

Backbone model.save() not appending ID to end of URL

I have an issue with a backbone PUT request returning 405 (Method not allowed). This is happening because the model.save() in the code is not sending to the model url with the ID of the model on the end.
This is the PUT.
Remote Address:::1:670
Request URL:http://localhost:670/api/contacts
Request Method:PUT
Status Code:405 Method Not Allowed
Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Authorization:Bearer YLPwKSpBsBrFUemRHdjz....
Connection:keep-alive
Content-Length:417
Content-Type:application/json
Host:localhost:670
Origin:http://localhost:660
Referer:http://localhost:660/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36
Request Payloadview source
{id:1, ContactOrganisation:Cow on a Mission, ContactPerson:Ben Drury, Phone:07980567574,…}
Address: "----"
ContactOrganisation: "----"
ContactPerson: "Ben"
CreatedBy: "----"
CreatedOn: "2014-03-03T16:40:50.037"
Description: "----"
Email: "---"
Organistion: "----"
Phone: "----"
Website: "http://www.cogiva.com"
id: 1
Response Headersview source
Access-Control-Allow-Headers:Authorization, Content-Type
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin:*
Allow:GET,POST,OPTIONS
Cache-Control:no-cache
Content-Length:72
Content-Type:application/json; charset=utf-8
Date:Thu, 17 Apr 2014 13:56:38 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
ConsoleSearchEmulationRendering
If I do the put through a REST console and add the id to the URL it works. But direct from this code:
this.model.set($(e.currentTarget).data("modelfield"), $(e.currentTarget).val());
console.log("model",this.model);
this.model.save({
success: function(model, response){
console.log("Yup!");
$(self.el).find('.update_loader').removeClass("running");
$(self.el).find('.update_loader').addClass("done");
},
error: function(){
console.log("No!");
$(self.el).find('.update_loader').removeClass("running");
$(self.el).find('.update_loader').addClass("error");
}
});
The model on the console just before the post, definitely had an ID. Why would it not be forming the URL correctly?
Model Def:
define([
'jquery',
'underscore',
'backbone',
], function ($, _, Backbone){
var ContactModel = Backbone.Model.extend({
url: "http://localhost:670/api/contacts"
});
return ContactModel;
});
Setting Model.url just gives the model a constant URL. If you want the model ID appended, then you need to specify Model.urlRoot instead. This will generate URLs of the form "/api/contacts/id":
var ContactModel = Backbone.Model.extend({
urlRoot: "http://localhost:670/api/contacts"
});
Alternatively, if the model is stored in a collection, then you could set Collection.url to the same. See the notes for Model.url:
Delegates to Collection#url to generate the URL, so make sure that you have it defined, or a urlRoot property, if all models of this class share a common root URL. A model with an id of 101, stored in a Backbone.Collection with a url of "/documents/7/notes", would have this URL: "/documents/7/notes/101"
You overwrite the url property. That's why it's fixed - backbone calls this property/function to get the url. And the default url function implementation uses urlRoot.
Change code to this should work:
var ContactModel = Backbone.Model.extend({
urlRoot: "http://localhost:670/api/contacts"
});
Check this: model.url
If your url format is special (not urlRoot/id) you need to overwrite url with a function to provide custom implementation.
You mask the default behavior of Model.url by setting an explicit url attribute on your ContactModel definition. Use Model.urlRoot instead:
var ContactModel = Backbone.Model.extend({
urlRoot: "http://localhost:670/api/contacts"
});