Using non-trivial REST API and Ember - django

We're new to Ember, and our intended (ember-cli) app first works by opening a project (which we can think of a JSON object), and then acting on various sections of that project with various functions. We have this "pick your project first" approach neatly encapsulated in a Django REST api structure, e.g.
/projects/ lists all projects
/projects/1/ gives information about project 1
/projects/1/sectionA/ list all elements in sectionA of project 1
/projects/1/sectionA/2/ gives information about element 2 of sectionA in project 1
/projects/1/sectionA/2/sectionB/... and so on.
We made relatively good progress with the first two points in Ember using ember-data and this.store('project').find(...) etc. However, we've come unstuck trying to add further to our url (e.g. points 3., 4., and 5.). I believe our issues come from routing and handling multiple models (e.g. project and sectionA).
The question: what is the best way to structure the routes in Ember.js to match a non-trivial REST API, and use ember-data similarly?
Comments:
the "Ember way", and stuff working out of the box is preferred. Custom adapters and .getJSON might work, but we're not sure if we'll then lose out on what Ember offers.
we want the choice of project to affect the main app template. E.g. if a project does not have "sectionA", then a link to "sectionA" is not displayed in the main app. And, if the project does have "sectionA", we need the link to be to e.g. "/project/1/sectionA", i.e. dependant on the project open.
This seems similar to handling users (i.e. first I must "pick a user" and then continue), where the problem is solved outside of the URL (and is similar to using sessions as we have done in the past). However, we specifically want the project ID to be inside the URL, to remain stateless.
Bonus questions (if relevant):
how would we structure the models? Do we need to use hasMany/belongsTo and, if so, is this equivalent to just loading the whole project JSON in the first place?
can ember-data handle such complex requests? I.e. "give me item 2 from sectionA of project 1"? Can it do this "in one go", or do there have to be nested queries (i.e. "first give me project 1" and then from this "give me sectionA" and then from this "give me item 1")?
Finally, apologies if this is documented well somewhere. We've spent nearly a week trying to figure this out and have tried our best to find resources -- it's possible we just don't know what we're looking for.

I think this one will be a good thing to read: discuss.emberjs.com/t/… - you've got Tom Dale and Stefan Penner involved in the thread
My suggestion would be to change it to query params:
/projects?id=1&selectionA=a&selectionB=b
then, you won't have such problems. And yes, you can still use all the hasMany and belongsTo fields.
If there's anything unclear, I'll provide you with a longer answer (if I'm able to).

Check out ember-api-actions and ember-data-actions also ember-data-url-templates
Here's a few more resources from a blog I found. ember-data-working-with-custom-api-endpoints and ember-data-working-with-nested-api-resources

Related

Google App Engine - Add & Reflect pattern, working around eventual consistency

I'm building a web application on app engine.
In my case, that's built on django-nonrel, but the key point is that it's using Google's datastore.
I love the fact that I don't need to deal with replication, sharding, backups and such, but one thing that is always getting in my way is the eventual consistency, which seems to get in the way of implementing a common web app pattern which I'm calling "Add & Reflect".
Let's say I have a project management app. The Project is its central model.
Now there's a web page page where I see a list of all projects, can add a project, and then I'll reflect back the list of all projects, which should include the project I just added (assuming no errors).
So the pattern goes like this:
Get and display list of existing projects
User adds new project (using a form on that page)
New project is created
As a response, get and display list of existing projects (now includes the new project)
Now the thing is, that due to eventual consistency, there is no guarantee whatsoever that I will get that new project when I get a list of all projects right after adding a new project.
Now that would be fine if this momentary inconsistency happened when another request (e.g. another user: user B) requested the list of projects one second after the project was added by the first user (user A), but it's really a problem when user A performs an operation, and does not see the results of his action, therefore does not get feedback.
I have gotten used to doing something like this to work around this problem:
def create_project(request):
response_context = {}
new_project = Project(name=request.POST['name'])
project.save()
response_context['projects'] = Project.get_serialized_projects()
# on GAE, eventual consistency means we are not guaranteed to see the
# new projects while querying for all projects, therefore we might need
# to add it manually...
if project.serialize() not in response_context['projects']:
response_context['projects'].append(project.serialize())
return render('projects.html', response_context)
The problem is that this happens in many places in my code, so I'm thinking maybe I'm missing something there, since this pattern is such a basic web app pattern.
Any suggestions for other ways to handle this?
Yes its a common issue. No theres no magic fix.
From client-side once you know the commit succeeded you can save the item locally (globals or storage) and then when querying from datastore merge your saved data. Put an expiration on it so its temporary. Its not trivial to make it work in all cases (say added an item then removed/renamed it so also update cache etc).
From server-side its common to cache recent saves in memcache and also merge with your queries.

Can a Custom DataProvider class expose Custom Templates?

I am currently in the process of writing a custom DataProvider. Using the Intergrate External Data documentation.
I've managed to show the external data in the Sitecore back end. However whenever I try to view the data in the items I created, I am getting an error
Null ids are not allowed. <br> Parameter name: displayName
There seems to be precious little on the subject on how to create a custom DataProvider on the Sitecore Developer Network.
The example on their website seems to only show how to import a SINGLE item into a static database. However I am simply trying to merge some items into the hierarchy and I can't find any useful documentation.
It seems that one of your methods that should return an ID doesn't. It might be GetChildIds and/or GetParentId.
Nick Wesselman wrote a good article about it gathering all the information including an example on the Marketplace. I think that is your best start. You can read it here.
Turns out I needed to include at the very least, the Fields->Section->Template in the GetParent method. To be on the safe side I included the Fields/Sections/Templates into my implementations of
GetChildIDs
GetItemDefinition
GetParentID
It wasn't obvious that this was the case, since I had in fact implemented the GetTemplates method correctly, and I had expected that should be enough.

RESTful API and Foreign key handling for POSTs and PUTs

I'm helping develop a new API for an existing database.
I'm using Python 2.7.3, Django 1.5 and the django-rest-framework 2.2.4 with PostgreSQL 9.1
I need/want good documentation for the API, but I'm shorthanded and I hate writing/maintaining documentation (one of my many flaws).
I need to allow consumers of the API to add new "POS" (points of sale) locations. In the Postgres database, there is a foreign key from pos to pos_location_type. So, here is a simplified table structure.
pos_location_type(
id serial,
description text not null
);
pos(
id serial,
pos_name text not null,
pos_location_type_id int not null references pos_location_type(id)
);
So, to allow them to POST a new pos, they will need to give me a "pos_name" an a valid pos_location_type. So, I've been reading about this stuff all weekend. Lots of debates out there.
How is my API consumers going to know what a pos_location_type is? Or what value to pass here?
It seems like I need to tell them where to get a valid list of pos_locations. Something like:
GET /pos_location/
As a quick note, examples of pos_location_type descriptions might be: ('school', 'park', 'office').
I really like the "Browseability" of of the Django REST Framework, but, it doesn't seem to address this type of thing, and I actually had a very nice chat on IRC with Tom Christie earlier today, and he didn't really have an answer on what to do here (or maybe I never made my question clear).
I've looked at Swagger, and that's a very cool/interesting project, but take a look at their "pet" resource on their demo here. Notice it is pretty similar to what I need to do. To add a new pet, you need to pass a category, which they define as class Category(id: long, name: string). How is the consumer suppose to know what to pass here? What's a valid id? or name?
In Django rest framework, I can define/override what is returned in the OPTION call. I guess I could come up with my own little "system" here and return some information like:
pos-location-url: '/pos_location/'
in the generic form, it would be: {resource}-url: '/path/to/resource_list'
and that would sort of work for the documentation side, but I'm not sure if that's really a nice solution programmatically. What if I change the resources location. That would mean that my consumers would need to programmatically make and OPTIONS call for the resource to figure out all of the relations. Maybe not a bad thing, but feels like a little weird.
So, how do people handle this kind of thing?
Final notes: I get the fact that I don't really want a "leaking" abstaction here and have my database peaking thru the API layer, but the fact remains that there is a foreign_key constraint on this existing database and any insert that doesn't have a valid pos_location_type_id is raising an error.
Also, I'm not trying to open up the URI vs. ID debate. Whether the user has to use the pos_location_type_id int value or a URI doesn't matter for this discussion. In either case, they have no idea what to send me.
I've worked with this kind of stuff in the past. I think there is two ways of approaching this problem, the first you already said it, allow an endpoint for users of the API to know what is the id-like value of the pos_location_type. Many API's do this because a person developing from your API is gonna have to read your documentation and will know where to get the pos_location_type values from. End-users should not worry about this, because they will have an interface showing probably a dropdown list of text values.
On the other hand, the way I've also worked this, not very RESTful-like. Let's suppose you have a location in New York, and the POST could be something like:
POST /pos/new_york/
You can handle /pos/(location_name)/ by normalizing the text, then just search on the database for the value or some similarity, if place does not exist then you just create a new one. That in case users can add new places, if not, then the user would have to know what fixed places exist, which again is the first situation we are in.
that way you can avoid pos_location_type in the request data, you could programatically map it to a valid ID.

Ember-Router: dynamically create state from a recursive path

I need a way for ember router to route to a recursive path.
For Example:
/:module
/:module/:submodule
/:module/:submodule/:submodule
/:module/:submodule/:submodule/...
Can this be done with Embers router, and if so, how?
I've been looking for examples, tearing apart the source, and I've pretty much come to the conclusion, it's not possible.
In a previous question, someone had pointed me to a way to get the url manually and split it, but I'm stuck at creating the state for the router to resolve to.
As of now, in my project, I currently just use the Ember.HashLocation to setup my own state manager.
The reason for the need of this, is because the module definitions are stored in a database, and at any given point a submodule of a submodule, recursively, could be added. So I'm trying to make the Application Engine handle the change.
Do your submodules in the database not have unique IDs? It seems to me that rather than representing your hierarchy in the path, you should just go straight to the appropriate module or submodule. Of course the hierarchy is still in your data model, but it shouldn't have to be represented in your routing scheme. Just use:
/module/:moduleId
/submodule/:submoduleId
And don't encode the hierarchy in the routes. I understand it might be natural to do so, but there's probably not a technical reason to.
If your submodules don't have unique ids, it's maybe a little tougher...you could build a unique ID by concatenating the ancestor ids together (say, with underscores), which is similar to splitting the URL, but a little cleaner probably. I will say that Ember/Ember Data doesn't seem to be too easy to use with entities with composite keys--if everything has a simple numeric key everything becomes easier (anyone want to argue with me on this, please explain to me how!).
DO you mean like this:
App.Router.map(function(match) {
match('/posts').to('blogPosts');
match('/posts/:blog_post_id').to('showBlogPost');
});

Opinion: Where to put this code in django app:

Trying to figure out the best way to accomplish this. I have inhereted a Django project that is pretty well done.
There are a number of pre coded modules that a user can include in a page's (a page and a module are models in this app) left well in the admin (ie: side links, ads, constant contact).
A new requirement involves inserting a module of internal links in the same well. These links are not associated with a page in the same way the other modules, they are a seperate many to many join - ie one link can be reused in a set across all the pages.
the template pseudo code is:
if page has modules:
loop through modules:
write the pre coded content of module
Since the links need to be in the same well as the modules, I have created a "link placeholder module" with a slug of link-placeholder.
The new pseudo code is:
if page has modules:
loop through modules:
if module.slug is "link-placeholder":
loop through page.links and output each
else:
write pre-coded module
My question is where is the best place to write this output for the links? As I see it, my options are:
Build the out put in the template (easy, but kind of gets messy - code is nice and neat now)
Build a function in the page model that is called when the "link placeholder is encountered) page.get_internal_link_ouutput. Essentially this would query, build and print internal link module output.
Do the same thing with a custom template tag.
I am leaning towards 2 or 3, but it doesn't seem like the right place to do it. I guess I sometimes get a little confused about the best place to put code in django apps, though I do really like the framework.
Thanks in advance for any advice.
I'd recommend using a custom template tag.
Writing the code directly into the template is not the right place for that much logic, and I don't believe a model should have template-specific methods added to it. Better to have template-specific logic live in template-specific classes and functions (e.g. template tags).