Django client side query construction - ajax

I'm making a pretty standard AJAXy (well, no XML actually) web page. The browser makes a bunch of API queries that return JSON to run the site. The problem is, I need to add to the API interface each time the page needs to do something new. The new API interface is usually little more than a database query followed by mapping the returned objects to JSON.
What I'd like to do is to get rid of all that server-side duplication and just have the page make database requests itself (using the model interface), but in a way that is safe (i.e. just read only ones). I think this would amount to an interface for constructing Q objects using JSON or something like that, and then send that up to the server, run the query, and return the results. Before I go making my own half-broken architecture for this, I'm wondering if this has already been done well. Also, is this even the best way to go about eliminating this duplication?
Thanks

Search multiple fields of django model without 3rd party app
Django SQL OR via filter() & Q(): Dynamic?
Generate a django queryset based on dict keys
Just replace with operator.and_ where appropriate.

Related

What is the purpose of API Resources?

I've read the docs and watched the Laracast. I'm still left wondering why you would use them?
I get that you can map different data to different names if your field names were to change but you want to keep a consistent public API. But surly you can just do the same on the model with the toArray() method and change the mappings there?
If I were to do:
return User::find(1);
I get a response like:
{"id":1,"name":"Ova Parker"}
If I do:
return new UserResource(User::find(1));
I get a response like:
{"data":{"id":1,"name":"Ova Parker"}}
Is there a significance in wrapping it with a data tag? I am just guessing but is this a standard JSON format for API's? Why would you not just do return User::find(1); instead of using an API resource, if this is under API routes then it'll return it as JSON anyway automatically.
You kind of answer the question by yourself. The idea behind API Resources or Transformers (like the ones from Fractal) is to hide the db field names from the client. With return User::find(1) you expose your whole db structure which might not a good idea security-wise and also bad for the release process. If you need to change a db field name, you have to change the API too. With Resources you have a mapping between your application and the consumer of you API.
It seems more work in the beginning, but once you started it, you won't wanna miss it anymore.
There is no toArray() method in PHP, which gets magically called like __toString(). You have to write you own and call it by yourself. Resources are built-in by Laravel and will be resolved automatically.

How can I use isValidJSValue to validate a query variable in my client code?

I'm writing client-side code for an app that will query a GraphQL server. In a couple of places in my code, I'm passing around data that will eventually get turned into a query variable, so it needs to validate against a specific GraphQLInputType in my schema. On looking into some of the utilities that graphql-js provides, it looks like the isValidJSValue checker is exactly what I'm looking for, and its comments even mention that it's intended to be used to do just that.
The issue is that I don't have access to the GraphQL type I want to validate against as a JS object, which is what I'm pretty sure that function is looking for. I'm importing my schema (as an npm depdendency) as JSON, or I also have it in the schema notation. Is there some other utility I can use to get the JS type I need from one of those sources, and then use that to check my data with isValidJSValue? Or is there some other way I could go about this that I just haven't thought of?
You can use the JSON schema you have imported to construct an actual GraphQL schema instance using buildClientSchema here: https://github.com/graphql/graphql-js/blob/master/src/utilities/buildClientSchema.js
Then, it should be a simple matter of looking in the types field of the resulting schema to find your input type, and then calling isValidJSValue on it.
I'm curious, though - why validate the value on the client before sending it, rather than just relying on the validation the server will do?

MiniProfilerEF view results without RenderIncludes()

Is there another way to view the profiling results of MiniProfiler (I'm specifically interested in EF5 version)?
Every tutorial that I've seen uses MiniProfiler.RenderIncludes(); but since my MVC app mostly returns JSON, that is not an option for me.
Is there a way to write results to file or something like that?
You can read and write results to just about anywhere by changing the MiniProfiler.Settings.Storage to a different IStorage implementation from the default (which stores to http cache). If you wanted to, this could store to and read from a file pretty easily (you would have to write your own custom implementation for that).
The files served by RenderIncludes are the html templates for displaying the results and the script to retrieve the results from the server and render them on the client (all found here). But you are by no means obliged to use this mechanism. If you want to write your own logic for retrieving and displaying results, you should base this off of the logic found in MiniProfilerHandler.GetSingleProfilerResult. This function roughly performs the following (putting in the siginificant steps for your purposes):
Gets Id of next results to retrieve (through MiniProfiler.Settings.Storage.List())
Retrieves the actual results (MiniProfiler.Settings.Storage.Load(id))
Marks the results as viewed so that they wont be retrieved again (MiniProfiler.Settings.Storage.SetViewed(user, id))
Converts these to ResultsJson and returns it
With access to MiniProfiler.Settings.Storage, you should be able to retrieve, serve and consume the profile results in any way that you want. And if you are interested in using the RenderIncludes engine but want to mess around with the html/js being served, you can provide your own custom ui templates that will replace the default behavior.

extJS4 difference between Ext.Ajax and Ext.data.proxy.Ajax

I am new to the extJS framework and after looking at these two classes I am curious when it is better to use one or the other. Is one better for submitting and one for getting? In my current situation I am using a grid and the api says to use the proxy.Ajax which I trust. But lets say I want to send the JSON back to a database, would I be better off using Ext.Ajax?
Also I am rather new to JSON I understand that its just a string with regular expressions essentially. What is the best way to send the json straight to a database if I don’t want to store the json locally?
Ext.Ajax is used to make one-off requests to a server. You can use this for GET and POST requests.
Ext.data.proxy.Ajax is used by the data package, in particular, Ext.data.Store's. You cannot use this 'manually'. You must use it via the data package.

Combining GET and POST in Sinatra (Ruby)

I am trying to make a RESTful api and have some function which needs credentials. For example say I'm writing a function which finds all nearby places within a certain radius, but only authorised users can use it.
One way to do it is to send it all using GET like so:
http://myapi.heroku.com/getNearbyPlaces?lon=12.343523&lat=56.123533&radius=30&username=john&password=blabla123
but obviously that's the worst possible way to do it.
Is it possible to instead move the username and password fields and embed them as POST variables over SSL, so the URL will only look like so:
https://myapi.heroku.com/getNearbyPlaces?lon=12.343523&lat=56.123533&radius=30
and the credentials will be sent encrypted.
How would I then in Sinatra and Ruby properly get at the GET and POST variables? Is this The Right Way To Do It? If not why not?
If you are really trying to create a restful API instead if some URL endpoints which happen to speak some HTTP dialect, you should stick to GET. It's even again in your path, so you seem to be pretty sure it's a get.
Instead of trying to hide the username and password in GET or POST parameters, you should instead use Basic authentication, which was invented especially for that purpose and is universally available in clients (and is available using convenience methods in Sinatra).
Also, if you are trying to use REST, you should embrace the concept of resources and resoiurce collections (which is implied by the R and E of REST). So you have a single URL like http://myapi.heroku.com/NearbyPlaces. If you GET there, you gather information about that resource, if you POST, you create a new resource, if you PUT yopu update n existing resource and if you DELETE, well, you delete it. What you should do before is th structure your object space into these resources and design your API around it.
Possibly, you could have a resource collection at http://myapi.heroku.com/places. Each place as a resource has a unique URL like http://myapi.heroku.com/places/123. New polaces can be created by POSTing to http://myapi.heroku.com/places. And nearby places could be gathered by GETing http://myapi.heroku.com/places/nearby?lon=12.343523&lat=56.123533&radius=30. hat call could return an Array or URLs to nearby places, e.g.
[
"http://myapi.heroku.com/places/123",
"http://myapi.heroku.com/places/17",
"http://myapi.heroku.com/places/42"
]
If you want to be truly discoverable, you might also embrace HATEOAS which constraints REST smentics in a way to allows API clients to "browse" through the API as a user with a browser would do. To allow this, you use Hyperlink inside your API which point to other resources, kind of like in the example above.
The params that are part of the url (namely lon, lat and radius) are known as query parameters, the user and password information that you want to send in your form are known as form parameters. In Sinatra both of these type of parameters are made available in the params hash of a controller.
So in Sinatra you would be able to access your lon parameter as params[:lon] and the user parameter as params[:user].
I suggest using basic or digest authentication and a plain GET request. In other words, your request should be "GET /places?lat=x&lon=x&radius=x" and you should let HTTP handle the authentication. If I understand your situation correctly, this is the ideal approach and will certainly be the most RESTful solution.
As an aside, your URI could be improved. Having verbs ("get") and query-like adjectives ("nearby") in your resource names is not really appropriate. In general, resources should be nouns (ie. "places", "person", "books"). See the example request I wrote above; "get" is redundant because you are using a GET request and "nearby" is redundant because you are already querying by location.

Resources