Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a REST API #27

Closed
almet opened this issue Aug 26, 2011 · 10 comments
Closed

Provide a REST API #27

almet opened this issue Aug 26, 2011 · 10 comments
Assignees
Milestone

Comments

@almet
Copy link
Member

almet commented Aug 26, 2011

All the things should be available trough a simple HTTP REST Interface.

@arnaudbos
Copy link
Contributor

Which format then? JSON?

  • Do you have hints on how to do it?

@almet
Copy link
Member Author

almet commented Aug 26, 2011

I think the format will be set by the http "ACCEPT" header. I'm thinking
about JSON, but we can serialize the data in different formats if we
want to.

For instance, if the request comes with a ACCEPT: XML, the web service
should be able to serialise the data as XML. I don't know what's the
mechanism to set the format of the sent data, but I'm pretty sure there
is something in the HTTP spec.

About how to do it, I'm thinking about different things. Currently, the
code is using the MVT (Model View Template) design pattern, wich is is a
slighly variation of the MVC pattern, returning directly HTML rendered
by the template enging. That's how views in flask (and I think they
borrowed this to Django) are working.

But there is a way to change this and we can, rather than return
directly return HTML from the views, return a dictionary of interesting
things. Which means that for the simple case of GET, we can return the
dictionary to a higher level interface and transform it using different
startegies (template processor if it is HTML, XML or JSON serialisers if
that's what asked and so on). I don't know exactly how I will proceed to
do so, but I think it is possible to add this either at the WSGI level
or in flask with a custom mechanism (I'm sure there is something that
could allow us to do so).

The other solution would be to continue using the template renderer but
make it render XML or JSON direcly (I mean, by hand), or by using some
specific serializers there.

I still have to dig a bit more into the APIs of Flask to see how this is
possible to be done simply.

Anyway, before finding out how it needs to be done, I think the need is
to define what will be exposed. I'm mainly tinking about the following
resources:

  • authentication (I'm not sure how I should make this. I'm not a big fan
    of oauth for this particular case, maybe basic authentication is the way
    to go. In this case we will need to add a certificate on the server and
    to sign it by CAcert, which will probably end up to be a mess).
  • project (add/edit/delete/list) I'm wondering if delete should be
    possible on the web service.
  • members (add/delete/list)
  • bills (add/edit/list)
  • balance (show) & simplified balance (to be implemented on the web
    interface as well)
  • archives (in the future, for now we can say that it will be a feature
    for the web interface only)

And that's it!

Are there some specific things that we should take into account about
the android plaform and the web service?

@arnaudbos
Copy link
Contributor

Sure there's a way, we just need to investigate as I personally discovered Django recently and, as with Flask, I have absolutely no idea on how to make it render different things.

Anyway I don't think the "by hand" solution is the way to go here.

Ok with the draft of the interface definition of the WS, an exception though about the project deletion.
I'm taking it from the point of view of an Android app, but in general, from a client, I'm really pissed of when there is limitations and I have to go the the online/web/main (you got it) version of a service to do stuff not accessible from the client.
My opinion is that if we play the game of a WS, we should play it from beginning till the end. Except during development obviously :)

And nope, I don't think about anything special required for Android especially...
Just write the service and the app will follow :)
I already have something in a box we can reuse for HTTP+JSON.
If it's HTTP+XML I'm sure just changing the parser will not be that hard.

@almet
Copy link
Member Author

almet commented Aug 27, 2011

I gave it some more thoughts, and I now think that we should put the maximum of logic about the models into the models themselves, same for the forms. The views should stay really simple (a bit more than they currently are) and then it will be easy to impelment a REST API.

I'm thinking that the end-user way to go should be with python decorators specifying the resource they are acting on, maybe the related model that comes from it and the rest could be directly built up by itself (well, we'll see if it's that easy)

I'm thinking about something like this:

@restify("/api/projects/")
class ProjectResource(Resource):
verbs = ["GET", "POST", "DELETE", "PUT"] # defaults
model = Project

def get(*args, **kwargs):
     # do something here, return a python dict.

and it would be easy to tweak the default behavior using methods named get, post etc.

This means some refactoring but hopefully not too much as we already took care of the separation of the logic when we could (so everything is not at the same place).

@arnaudbos
Copy link
Contributor

Well... I'm lost :D Huh
We better talk about it more deeply in private and post a summary here to reduce the feed length, don't you think?

@almet
Copy link
Member Author

almet commented Aug 28, 2011

I don't think going private is a good idea, as @fredericsureau and others would be interested to take part in the discussion.

Why are you lost? What's unclear? Anyway, I'll probably go for the implementation of it and you'll probably understand more clearly ("talk is cheap, show me the code").

@arnaudbos
Copy link
Contributor

I meant, just for the part where you explain it to me more in deep :)

But yeah, show me the code :)

almet added a commit that referenced this issue Sep 11, 2011
Introduces the "rest" module, with reusable utils for flask applications (will be packaged as a flask extension later on).
@almet
Copy link
Member Author

almet commented Sep 13, 2011

I've impemented basic stuff in the repository, that's under the modules rest and api. The stuff in rest had been made to be reusable (so we can use it in other flask projects as well, I should make it a flask extension).

What's missing is the creation and update of resources. It is possible to retrieve a list, an element and to delete stuff for now. The only serializer so far is the json one, and I think we should stick to it, nope? If we are in need of a XML serialization, I would be able to implement it quickly.

@ghost ghost assigned almet Sep 13, 2011
@arnaudbos
Copy link
Contributor

From my point of view JSON is by far more pleasant to use so I'm happy you did it first :)
Now it's clear that if a XML serializer is needed later on, it will be easy to implement one as you said.

Very good job by the way, I had no idea how this could be achieved at first, but everything became clear when reading your code.

Edit: Maybe it's the good time to consider starting a doc?

@almet
Copy link
Member Author

almet commented Sep 13, 2011

I've implemented creation and update as well. I'm +1 on a doc (I'm thinking about a way to auto-generate it), and I want to add some tests as well to be sure the code is working in all edge cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants