We have a nested JSON structure in our web app on the frontend like Rows > Columns > Elements > Rows > Columns > Elements ...
We also have an API call which sends the entire data as JSON to backend.
In the backend we have a set of several permissions, like column size change, row background change, element ordering change, etc that are permitted or denied for various types of users.
We want to identify in the backend if the change of the nested structure is permissible.
Example 1 [Update data]:
The user has CHANGED the size of a 'Column', where the size is represented as a property in 'Column' object.
or
Example 2 [Remove/Add data]:
The user has removed/added an 'Element' from a 'Column'.
We know that we can do full traverse on the entire tree, and understand if the change was permissible or not, but we are looking for a better and faster, resource saving solution for concurrent connections and many users/big trees.
This question seems to be general for different technologies, but I want to let you know that we are using Laravel / Lumen / Dingo in the backend & Ember.js on the frontend.
Thanks for reading and helping :)
One option is to not send the entire JSON to the server, but to instead send json patch (see http://jsonpatch.com/). Then on the server, have rules that affectively hash the paths in the patch to permissions. In other words, since you are only sending the change and not the entire JSON, the need to parse the entir
You can have a API for returning permissions (have model Permission).
Then check for that permission for any actions you need in frontend by using ember-can.
By this, you can ensure that when you send back data for updating from front to back, it is complying the permissions defined in backend and no need for many back n forth
I think you can have type for each change. For example column change is ----> colChange(or simpleChange). Send the type of change with json. Permission can be checked by change type. Also there can be groups of change types and permission can be sat to groups. In case if you don't send data for each change there must be stack of user changes(push type of change into stack on each user change). Send that stack with json to backend .
Related
I have a doubt. When is a GET request sent. I mean, I have seen a lot of people using if request.method == 'GET', when they render the form for the first time, but when the form is submitted, they do a `POST' request.
While they explicitly mention when defining the form in html that the method will be 'POST', they don't do the same for 'GET' request which is made when an empty form is requested.
How does django know it's a GET request?
And, why is it done so?
Thanks,
I'm not an expert but I think Django "knows" this because like all things on the Internet it uses the HTTP protocol. There are several HTTP methods. If not specified the default method will always be GET
GET
A GET is usually used to retrieve information. Typically a GET function has no side-effects (this means that data in the database is not changed, that no files in the filesystem are modified, etc.).
Strictly speaking this is not always true, since some webservers log requests (themselves) and thus add an entry to the database that a specific user visited a specific page at a specific timestamp, etc.
A typical GET request is idempotent. This means that there is no difference between doing a query one time, or multiple times (two times, three times, five times, thousand times).
GET queries are therefore typically used to provide static content, as well as pages that contain data about one or more entries, search queries, etc.
POST
POST on the other hand typically ships with data (in the POST parameters), and usually the idea is that something is done with this data that creates a change in the persistent structures of the webserver. For example creating a new entry in some table, or updating the table with the values that are provided. Since these operations are not always idempotent, it can be dangerous if the user refreshes the page in the browser (since that could for example create two orders, instead of the single order the user actually wanted to create).
Therefore in Django a POST request will typically result in some changes to the database, and a redirect as result. This means that the user will typically obtain a new address, and perform a GET request on that page (and that GET is idempotent, hence it will not construct a new order).
PUT, PATCH and DELETE
Besides the popular GET and POST, there are other typical requests a client can make to a webserver. For example PUT, PATCH and DELETE.
PUT
PUT is the twin of a POST request. The main difference is that the URI it hits, specifies what entry to construct or update. PUT is usually an idempotent operation.
This means that if we would for example perform a POST server.com/blog/create to create a blog, PUT will typically look like PUT server.com/blog/123/. So we specify the id in advance. In case the object does not yet exists, a webserver will typically construct one. In case the entity already exists, a new entity will typically be constructed for that URI. So performing the same PUT operation twice, should have no effect.
Note that in case of a PUT request, typically one should specify all fields. The fields that are not specified will typically be filled in with default values (in case such values exist). We thus do not really "update" the entity: we destroy the old entity and create a new one in case that entity already exists.
PATCH
PATCH is a variant of PUT that updates the entity, instead of creating a new one. The fields that are thus missing in a PATCH request, typically remain the same as the values in the "old" entity so to speak.
DELETE
Like the name already suggests, if we perform a DELETE server.com/blog/123/ request, then we will typically remove the corresponding element.
Some servers do not immediately remove the corresponding element. You can see it as scheduling the object for deletion, so sometimes the object is later removed. The DELETE request, thus typically means that you signal the server to eventually remove the entity.
Actually Django is based on HTTP responses-requests. HTTP is fully textuall. So Django parses each request and finds in its header information about what kind of request is it. I may be mistaken in details, but as I understand when server receives request - Django creates it's object request, which contains all the data from HTTP. And then you decide if you need a specific action on GET or POST and you check the type of request with request.method.
P.S. And yes, by default each request is GET.
I have a following architectural question - my application back-end is written at Java and client side at AngularJS. Right now I need to store the user input on the page in order to be able to share and bookmark my application urls and restore the state by this url.
I'm going to implement the following approach - every time the user interacts with my application via selecting the data and conditions at the page I'll collect all of his input at a complex JSON document and store this document at Elasticsearch. Key of this document from ES I'll send back to client application(AngularJS) and based on this key I'll update the page url. For example the original url looks like:
http://example.com/some-page
based on a key from server I'll update this url to following:
http://example.com/some-page/analysis/234532453455
where 234532453455 is a key of a document in ES.
Every time the users will try to access the following url - http://example.com/some-page/analysis/234532453455 AngularJS application will try to get a saved state by key (234532453455) via Java backend REST endpoint.
Will it work ?
Also, I'm in doubt right now how to prevent the duplication of the documents in ES. Right now I have no experience with ES so don't know what approach from ES can be used out of the box for this purpose.
For example is it a good idea to calculate some hash code of each JSON document and store this hash code as a key of a document.. so before storing the new document I can check the old document by hash code. Also performance is very important to me so please take this into account also.
For me it sounds you try to implement cache.
Yes you can do this but if you will use ES only for this solution then I think you should better look to redis or memcached.
I can't say that ES is bad solution for this but ES has some tricks which you must remember for instance its near realtime search. After you index data they are not immediately available to search it takes few seconds depends on configuration(But you can also call _refresh but I am not sure about performance if you index data very often).
Hash: I dont see reasons to use has I'd better create right id. So if you have types of reports per user than id could be "reporttype_{userid}", because if you will use hash as an ID then each new object will have new id and instead of rewriting you will end up with having many copies of old data for that user. if you go with pattern reporttype_{userid} then each time when user regenerate report with new data you will just override it.
As an option you could add to that option fields userid and expireat for future cleanup, for instance you could have job which will cleanup expired reports, but this is valid only if you go with ES, since in redis and memcached there is option to set expiration when you save data
A REST API can have arguments in several places:
In the request body - As part of a json body, or other MIME type
In the query string - e.g. /api/resource?p1=v1&p2=v2
As part of the URL-path - e.g. /api/resource/v1/v2
What are the best practices and considerations of choosing between 1 and 2 above?
2 vs 3 is covered here.
What are the best practices and considerations of choosing between 1
and 2 above?
Usually the content body is used for the data that is to be uploaded/downloaded to/from the server and the query parameters are used to specify the exact data requested. For example when you upload a file you specify the name, mime type, etc. in the body but when you fetch list of files you can use the query parameters to filter the list by some property of the files. In general, the query parameters are property of the query not the data.
Of course this is not a strict rule - you can implement it in whatever way you find more appropriate/working for you.
You might also want to check the wikipedia article about query string, especially the first two paragraphs.
I'll assume you are talking about POST/PUT requests. Semantically the request body should contain the data you are posting or patching.
The query string, as part of the URL (a URI), it's there to identify which resource you are posting or patching.
You asked for a best practices, following semantics are mine. Of course using your rules of thumb should work, specially if the web framework you use abstract this into parameters.
You most know:
Some web servers have limits on the length of the URI.
You can send parameters inside the request body with CURL.
Where you send the data shouldn't have effect on debugging.
The following are my rules of thumb...
When to use the body:
When the arguments don't have a flat key:value structure
If the values are not human readable, such as serialized binary data
When you have a very large number of arguments
When to use the query string:
When the arguments are such that you want to see them while debugging
When you want to be able to call them manually while developing the code e.g. with curl
When arguments are common across many web services
When you're already sending a different content-type such as application/octet-stream
Notice you can mix and match - put the the common ones, the ones that should be debugable in the query string, and throw all the rest in the json.
The reasoning I've always used is that because POST, PUT, and PATCH presumably have payloads containing information that customers might consider proprietary, the best practice is to put all payloads for those methods in the request body, and not in the URL parms, because it's very likely that somewhere, somehow, URL text is being logged by your web server and you don't want customer data getting splattered as plain text into your log filesystem.
That potential exposure via the URL isn't an issue for GET or DELETE or any of the other REST operations.
I am working with an existing web api. I upload a list of JSONObjectA to the server this then returns a list of JSONObjectB. This all works fine and I am happy with that. A problem arises when I send a list of 1 to the server. Instead of a List of one being returned, I only receive JSONObjectB. This means I need different Serializers to parse the data.
Would it make more sense for the server to always return a list (ie. always the same object) or would it be considered good practice to do it the current way?
It would make more sense to always return a list. When building an API you should always go for ease of use, and having 2 different types returned means that the API user has to do additional work that they shouldn't need to.
I'm attempting to move an existing (and working) client-side jQuery validation schema to JSONSchema to allow myself to validate arbitrary JSON on both the client and server.
My application is essentially a bunch of gigantic forms with lots of complex logic determining which questions should be asked based on the user's response to other questions. The forms each have over 200 fields.
Right now I'm only doing client-side validation and that works well about 99% of the time. Browser issues have cropped up on a few occasions, but nothing catastrophic. That being said, I want to do server-side validation (!).
After reading the JSONSchema draft and browsing around some of the v3 implementations, it seems like I might lose some of the more complex rules that my application has come to depend upon. I want to be sure that I'm not missing something before moving too far in any direction.
Some examples:
"If x == 10, then y is required, otherwise it's optional"
10 could be a literal value, an enum, etc., but I need to be able to reference another field in the same structure and guarantee it's value not only exists, but is equivalent to a specific type / value.
I think this is addressed in this thread on the JSONSchema list.
"If x = today's date, and y = tomorrow's date, then x > y"
This logic will be used to ensure that the "from" date comes before the "to" date.
From what I can see there's nothing like this and the only way I can see doing it is passing in a freshly eval-ed chunk of JSON as the schema.
The closest thing I've found to meet the above needs is CERNY.
If I'm barking up the wrong tree, please let me know. I'm also looked into running backbone.js on both the client and server.
tl;dr;
I want to maintain one set of validation rules for large and complex forms and apply these validation rules to arbitrary JSON documents on both the client and server side.
there is many tricks but not all of them are possible. For example
if x == 10 then y is required can be achieved with something like (draft 3):
"type":[
{"properties":{"x":{"enum":[10]}, "y":{"required":true}}},
{"properties":{"x":{"disallow":[{"enum":[10]}]}}}
]
Let's say, it's possible but very tricky… a schema is basically supposed to validate the structure, not it's content (even if there is few properties for this)
Another possible way I personally do like is to "extend" the current validation graph with an external url based schema. The idea is to send parameters of the current document on an url which one will return a relevant schema according to those parameters.
Example:
{
"extends":{"$ref":"http://checkCustomValidity/{x}/{y}/"};
}
Where at "runtime" the schema sent back could be a {"disallow":"any"} if not allowed or {} if ok
This is useful as the url can be both used for the client and server side (your client will not be completely standalone but in some cases, you just cannot)
A real life usage for this is in cases where it is obliged to use a remote service. For example if I do have to check if my nickname is already used on the server during the registration. I code a server side web service answering to the request path: http://www.server.com/isNicknameUsed/{nickname}