Is it possible in Sailsjs to build more complex models - sails.js

I would like to have arrays or collections in my model, is this yet possible with waterline (mongoDB)? are there any alternatives around?
example:
{
name: Bundle,
col1 : {
name : anOtherModel,
subCol: {
text: aString,
...
}
},
col2 : {
name : anOtherModel,
subCol: {
text: aString,
...
}
}
}
to:
module.exports = {
attributes : {
name : {
type : 'STRING',
required : true
},
basicModules: {
type : 'ARRAY', // or 'COLLECTION'
required : false
}
}
};

I don't know if this is still an issue, but the trick is to neither POST as "form-data" nor "x-www-url-encoded". You have to POST the "raw" content:
Assume the situation:
http://www.example.com/mymodel
form-data
Your Header may look like this:
POST /mymodel/create HTTP/1.1
Host: www.example.com
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="basicModules"
[1,2,3,4]
----WebKitFormBoundaryE19zNvXGzXaLvS5C
the result is that a string "[1,2,3,4]" gets (type-)validated, which fails
x-www-url-encoded
In this case the Header is something like this:
POST /mymodel/create HTTP/1.1
Host: www.example.com
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
basicModules=%5B1%2C2%2C3%2C4%5D
which has exactly the same result as form-data. validation fails because of basicModules being the string "[1,2,3,4]"
raw
to make it work your Header has to look like this:
POST /mymodel/create HTTP/1.1
Host: www.example.com
Cache-Control: no-cache
{"basicModules":[1,2,3,4]}
which results in just exactly what you want, and type validation works.
so in the end, you can fill the most complex models that way in JSON. e.g.
POST /mymodel/create HTTP/1.1
Host: www.example.com
Cache-Control: no-cache
{"user": {
"name": {
"first":"John",
"last":"Doe"
},
"age":25,
"pets":[{
"name":"Garfield",
"type":"cat"
},
{
"name":"Rudolph",
"type":"reindeer"
}]
}

If you're looking for model associations, it's not there yet (look at this issue for proposed implementations) if you'd just like to have arrays of data stored in DB, you can have arrays as attribute (see the doc for reference on that). I haven't tested it but I guess it will serialize the array prior to saving it in the DB if it doesn't have a matching structure.

Related

Swagger Validator complaining about seemingly well-formed request

I'm using the swagger-express-validator to validate inputs to a small API server (using Swagger 2 format)
My path definition is as follows
/api/v1/users:
post:
produces:
- "application/json"
parameters:
- in: body
name: ids
description: Array of user ids to be processed
required: true
schema:
$ref: "#/definitions/ArrayOfIds"
responses:
200:
description: success
ArrayOfIds is defined as follows
Id:
type: string
ArrayOfIds:
type: array
items:
$ref: "#/definitions/Id"
Sending a post request to the server as follows:
POST /api/v1/users HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: localhost:3000
Connection: close
User-Agent: Paw/3.1.7 (Macintosh; OS X/10.13.6) GCDHTTPRequest
Content-Length: 35
{
"ids": ["abcd12345"]
}
Results in an error
Request Invalid: POST /api/v1/users
[ { keyword: 'type',
dataPath: '',
schemaPath: '#/type',
params: { type: 'array' },
message: 'should be array' } ]
I am however able to access req.body.ids in my Express route controller code and it contains the correct value ['1234abc'].
Do you have any idea as to why the validator is complaining about the request? It looks fine to me.
Your request body does not match the definition. According to the definition, the array in the request body must be unwrapped:
POST /api/v1/users HTTP/1.1
Content-Type: application/json
...
["abcd12345"]
If the array needs to be wrapped into the ids wrapper property, the request body should be defined as type: object with the property ids that contains the array:
parameters:
- in: body
name: ids
description: Array of user ids to be processed
required: true
schema:
type: object
properties:
ids:
$ref: "#/definitions/ArrayOfIds"

JSON encoded exceptions in TYPO3 extbase controller with JsonView

For my extbase-based TYPO3 CMS extension I created an ApiController with JsonView as view object. Returning values works like a charm, the correct header Content-type: application/json is set.
To return other responses like missing authorization messages or validation errors, I currently use:
$data = ["errors" => [
"status" => 401,
"message" => "Missing access token"
]];
$this->throwStatus($status, null, json_encode($data));
When I use $this->throwStatus() the header Content-type: text/html is set. Even if I manually set header("Content-type: application/json"); before using $this->throwStatus().
How can I create responses with the correct content type header?
Before you throw the status, try to set the headers in the response object:
$this->response->setHeader('Content-Type', 'application/json', true);
$this->response->sendHeaders();
If you are accessing your data through a dedicated pageType, you can set the header for this pageType in TypoScript:
myPageType.config.additionalHeaders {
10 {
header = Content-Type: application/json
replace = 1
}
}
I will add this to my post about the topic: https://usetypo3.com/json-view.html

"Resource Not Found" message received when sending a query to Keen IO API

I am using Advanced REST Client tool to test a data pull from the Keen IO API, and think getting the request right, but not getting the data. Getting "resource not found" error. This can also be done via CURL.
Headers: Authorization:
Content-Type: application/json
actual request: GET /3.0/projects//queries/saved/Sponsorships/result HTTP/1.1
HOST: api.keen.io
authorization:
content-type: application/json
Base URL used: https://api.keen.io
Any ideas as to what may be doing wrong?
The saved query name is capitalized "Sponsorships". Make sure your saved query name is lower-cased, not camel or title-cased. To be sure that you are getting the correct saved query name.
Also, you may want to first obtain a list of all saved queries as a reference:
GET /3.0/projects/<project_name>/queries/saved HTTP/1.1
HOST: api.keen.io
authorization: <your_key>
content-type: application/json
You will get something like this:
[
{
"refresh_rate": 0,
"last_modified_date": "2016-12-20T01:09:54.355000+00:00",
"query_name": "",
"created_date": "2016-12-20T01:09:54.355000+00:00",
"query": {
"filters": [],
"latest": 100,
"analysis_type": "extraction",
"timezone": "UTC",
"timeframe": "this_30_days",
"event_collection": ""
},
"metadata": {
"visualization": {
"chart_type": "table"
},
"display_name": ""
},
"run_information": null
}
]
FWIW, I also have seen the "Resource not found" error when writing data to an event if the project is not correctly set up. For example, passing in the wrong project_id or write_key or if the project was deleted from your Keen.io account.

While trying to access RedHat BRMS kie server, i am not able to use POST/PUT methods through rest client

Trying to access POST data through rest client, getting 405.
The response headers states Allow: GET, OPTIONS, HEAD.
So how can I make my rest container accept POST/PUT methods?
EndPoint http://localhost:8080/kie-server/services/rest/server Request Headers used -
Content-Type: application/json
authorization: Basic !#$#%&$$(((
Accept: application/json
X-KIE-ContentType: JSON RESPONSE HEADERS
Server: Apache-Coyote/1.1
Allow: GET, OPTIONS, HEAD
Content-Type: text/html;charset=utf-8
Content-Length: 1088
Date: Thu, 01 Sep 2016 08:43:33 GMT
Tried using Advanced rest client,curl and java code but Same results :(
Referred - https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_BRMS/6.3/html/Getting_Started_Guide/chap-Hello_World_rule_example.html
I think you have to change the Endpoint (URL). I would suggest
http://localhost:8080/kie-server/services/rest/server/containers/instances/("nameOfYourDeployment")
Or try without instances.
In Rest Client provide the following set of values:
URL:
http://localhost:8080/kie-server/services/rest/server/containers/instances/<name-of-your-container>
HEADER:
Accept: application/json
Content-Type: application/json
select method type POST and your JSON request payload
When you hit the API it will ask you for the username and password provide the credentials.
fou can send
payload
as:
{
"commands": [
{
"insert": {
"out-identifier": "Input",
"return-object": "true",
"object": {
"<complete-package-name>.<class-name>": {
"variable-1" : "value-1",
"variable-2" : "value-2"
}
}
}
},
{
"fire-all-rules": {
"outIdentifier": "output"
}
}
]
}

How can I prevent Ext JS from including an entity body in DELETE requests using a restful store?

When Ext JS issues a DELETE request from a restful store, it includes an entity body. Although this doesn't seem to be forbidden by the HTTP spec, Google App Engine doesn't accept such requests. So I'd like to know if there is a way to prevent a restful store from including a redundant entity body on DELETE requests.
Details:
Using this sample as reference:
http://www.sencha.com/deploy/dev/examples/restful/restful.html
This is how the store is defined:
var store = new Ext.data.Store({
id: 'user',
restful: true, // <-- This Store is RESTful
proxy: proxy,
reader: reader,
writer: writer
});
After pressing the "Delete" button, this is the request Ext JS sends:
DELETE http://www.sencha.com/deploy/dev/examples/restful/app.php/users/6 HTTP/1.1
Host: www.sencha.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; pt-BR; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: pt-br,pt;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Content-Type: application/json; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://www.sencha.com/deploy/dev/examples/restful/restful.html
Content-Length: 10
Cookie: bb_sessionhash=8d75f5e42d576fb695a02bf1d24c9ff1; etc...
{"data":6}
When a request in this format (with the "data" content) is submitted to Google App Engine, it replies with:
400 Bad Request
You can fix this problem, as you guessed, by overriding a method in the HttpProxy class. First, add this code:
// Special HttpProxy that sends no body on DELETE requests
Ext.data.GAEHttpProxy = Ext.extend(Ext.data.HttpProxy, {
doRequest: function(action, rs, params, reader, cb, scope, arg) {
if(this.api[action]['method'].toLowerCase() == "delete") {
delete params.jsonData;
}
Ext.data.GAEHttpProxy.superclass.doRequest.call(this, action, rs, params, reader, cb, scope, arg);
}
});
Then, use this new class ("GAEHttpProxy") instead of HttpProxy in the rest of your code (for instance, when you create the proxy you use in your store shown above). This worked for me, and I hope it works for you!
Although the question is asked 7 years ago and we have sencha 6 now, the problem isn't solved OOTB yet. So here is my working solution:
Ext.define('My.Proxy', {
extend: 'Ext.data.proxy.Rest',
writer: {
type: 'json',
writeAllFields: true, // may be false, as you wish
transform: {
fn: function(data, request) {
return request.config.action === 'destroy' ? null : data;
},
scope: this
}
}
});
We could also do this check: request.config.method === 'DELETE' but for some reason it always returns false. So I recommend to stay with action === 'destroy'