On Tue, Jun 3, 2014 at 4:00 AM, Stephen McDonald <[email protected]> wrote:
>
> On Tue, Jun 3, 2014 at 7:23 AM, Sanjay Bhangar <[email protected]>
> wrote:
>>
>> <Snip />
>>
>> What's the best way to go ahead with this?
>
>
> I earlier mentioned creating a separate repo called mezzanine-rest-api or
> something similar, but I've been thinking about this a bit more and have
> some other possible ideas. Mezzanine has always had a "kitchen sink"
> philosophy, in as much as if a particular feature is arbitrarily deemed
> common enough (eg not all, but *most* sites need a blog), then we include
> it. We also have the approach of implementing our own code if the feature
> can be achieved simply enough, only deferring to dependencies when the
> feature is too broad to implement from scratch. The case of a REST API and
> django-rest-framework clearly fit this bill, in that we wouldn't try and
> recreate what it does. I too have worked with DRF quite extensively over the
> last 12 months, and I feel like the actual backend API code for Mezzanine
> would be fairly minimal when leveraging it.
>
> So to sum up:
>
> - In 2009 when Mezzanine started, a REST API probably wasn't common enough
> to warrant inclusion in Mezzanine. Now in 2014 I think it is.
> - If we defer to DRF as a dependency, which from my experience has been very
> stable, the code should be minimal enough in Mezzanine to warrant inclusion,
> eg the maintenance overhead in this case would be acceptable given the
> benefit of having this feature work out of the box.
>
> In terms of implementation, my idea would be to create a "mezzanine.api"
> package that simply houses the view (and serializer in DRF-speak) code in
> one spot for all the other apps. This may seem like it goes against the
> notion of Django applications and isolation within them, and that we should
> build REST API code within each individual app (blog, pages, etc), but I
> don't see it that way structurally - I feel like the REST API is a single
> feature of Mezzanine as a whole, that belongs in its own app that can be
> turned on or off. I think of it in terms of the URLs exposed, would you
> expect a single root endpoint for the API like:
>
> /api/blog/
> /api/pages/
>
> or endpoints littered throughout the URL structure like:
>
> /pages/api/
> /blog/api/
>

I agree with the idea of a separate mezzanine.api package, also
probably makes it easier for the user to turn off if they don't want
it. I prefer URLs like /api/blog instead of /blog/api , and then /api/
having an api "root" that has some docs, links to all end-points. When
designing APIs, we generally add versioning, which would make it
/api/v1/blog, but in Mezzanine's case, versioning may not be
necessary. Of course, would defer to you on the decision around URL
structure.

> I've worked on projects with both approaches in terms of URL structure and
> "Django app" structure, and having both aspects follow the former pattern
> above really feels right.
>
> From that point I think we'd start designing things to more or less mimic
> the design of admin classes throughout Mezzanine - these represent the
> common interfaces for crud operations (via Django admin). So we'd have
> something that maps to Displayable and could be re-used by project specific
> models that subclass Displayable - we'd then use that in mezzanine.api to
> implement the blog's REST API.
>

That seems very sane. My guess is a base Serializer class that maps
roughly to Displayable, and then models can subclass the serializer
for their needs, and then views can call the appropriate Serializer
class. I see Mezzanine uses function-based views for most of its
views? In general, I prefer FBVs myself, but with
Django-Rest-Framework, I've enjoyed using and extended the class-based
views - does that sound okay?

I've generally ignored the Rest-Framework "Viewsets" for my own
projects because its always seemed like too much magic, but this maybe
a good use-case for them instead of individual "view" classes - will
look into the options a bit.

> That should be pretty straight-forward. The stuff for pages will get a
> little trickier:
>
> - How do we represent a tree in a REST API without hammering the web server,
> in the same way Mezzanine originally solved the problem for rendering trees
> without hammering the database with recursive queries.

Right, so this is both a representational problem, i.e. what JSON
structure should this tree structure have in the API + of course, a
database / optimization problem. It does sound potentially a bit
complex. I think perhaps a good start maybe to just spec out the API a
bit? Chalk out end-points, what query parameters, etc. they should
expect, what they should return, etc? Of course, one would, as far as
possible, follow Rest-Framework conventions, but it would probably be
good to have a rough map of desired end-points, query params, etc.
And, for stuff like nested representations, some discussion around
desired JSON structure, etc. I get the sense that it maybe good to try
and keep the JSON structure flat, and perhaps just have something like
a 'parent_page' field which points to the parent page, instead of
having a nested JSON structure, but I am unfamiliar with code for
nested pages at this point, so that may not even really make sense.

Is there a good place to start putting up some sort of API 'design'
document? Github issue? Some wiki? Just the mailing list?

> - How do we have the REST API automatically expose project specific Page
> subclasses, in the same way the admin currently does?
>

Will look at this code and see if I get any ideas :)

> That's all I have in mind for now. Both ideas of including this within
> Mezzanine, and putting everything into a single mezzanine.api package are
> probably hot topics for debate, although I'd normally be the one rallying
> against including large new changes in Mezzanine itself. But again, I think
> the development landscape in 2014 warrants a REST API out of the box.
>

Ha, it's really exciting that you as maintainer feel this way, and
really hope the community can pull up their socks and support / make
this happen. DRF seems like a solid backbone, and it would be great to
see these two things come together.

So far I just checked out the mezzanine code, created a branch, and
added rest-framework stuff to requirements, etc. - going to try and
create 1-2 simple views for things perhaps and try and push code out
to just try and generate a bit of discussion - there probably are a
lot of little design decisions along the way, which are probably
especially important since the idea is to have this as a core
mezzanine feature.

Anyways, need to catch up on other work - hopefully I can come back to
this tonight and have some boilerplate that I can push to get some
feedback / discussion.

Cheers,
Sanjay

-- 
You received this message because you are subscribed to the Google Groups 
"Mezzanine Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to