2009-07-20 7 views
0

Je suis en train de créer un service web REST qui expose le modèle Django suivant:Comment exposer un modèle Django en tant que service Web RESTful?

class Person(models.Model): 
    uid = models.AutoField(primary_key=True) 
    name = models.CharField(max_length=40) 
    latitude = models.CharField(max_length=20) 
    longitude = models.CharField(max_length=20) 
    speed = models.CharField(max_length=10) 
    date = models.DateTimeField(default=datetime.datetime.now) 

    def __unicode__(self): 
     return self.name 

Voilà comment je pensais à ce sujet jusqu'à présent:

Obtenez toutes les personnes
URL:http://localhost/api/persons/
Méthode:GET
Q uerystring:

  • startlat=
  • endlat=
  • startlng=
  • endlng=

Utilisé pour obtenir les personnes qui sont dans la plage de coordonnées spécifié.

  • page=

Utilisé pour obtenir la page spécifiée de la réponse (si la réponse contient plusieurs pages).

Retours:

  • 200 OK & JSON
  • 404 Not Found

Exemple:
Demande:

GET http://localhost/api/persons/?startlat=10&endlat=15&startlng=30&endlng=60 

Réponse:

{ 
    "persons": 
    [ 
    { "href": "1" }, 
    { "href": "2" }, 
    { "href": "3" }, 
    ... 
    { "href": "100" } 
    ], 
    "next": "http://localhost/api/persons/?startlat=10&endlat=15&startlng=30&endlng=60&page=2" 
} 


Informez-vous sur une personne spécifiée
URL:http://localhost/api/persons/[id]
Méthode:GET
Retours:

  • 200 OK & JSON
  • 404 Not Found

Exemple:
Demande:

http://localhost/api/persons/5/ 

Réponse:

{ 
    "uid": "5", 
    "name": "John Smith", 
    "coordinates": { 
        "latitude":"14.43432", 
        "longitude":"56.4322" 
       }, 
    "speed": "12.6", 
    "updated": "July 17, 2009, 8:46 a.m." 
} 



À quel point ma tentative est-elle correcte? Toutes les suggestions sont très appréciées.

Répondre

3
{ "href": "1" }, 

1 est à peine une URL valide. Vous devriez utiliser des URL complètes. Google pour HATEOAS.

En outre, n'oubliez pas d'envoyer un en-tête Content-Type pertinent. Vous pouvez créer votre propre type mime pour décrire le format. Cela vous donne la possibilité de changer plus tard le type de contenu (par exemple changer le format après la publication). Voir Versioning REST Web Services

+0

Merci! Pendant la conception du service, j'ai lu un article (http://bitworking.org/news/restful_json/) qui m'a incité à utiliser des URL relatives. Pourquoi pensez-vous que l'utilisation d'URL relatives n'est pas une bonne idée? –

+1

Alors que les URL relatives sont probablement correctes en théorie, elles présentent un problème dans la pratique. Il est très probable qu'un client va coder en dur la construction de l'URL, plutôt que de réellement résoudre l'URL relative. Cela rend votre api fragile. D'un autre côté, qu'est-ce que vous gagnez en rendant les URL relatives? Si c'est la performance, pensez à utiliser la compression, ce qui supprimera la redondance assez efficacement. Sur une note de côté - N'oubliez pas de mettre vos ressources en cache (Send Etags et expires-headers) – troelskn

+0

J'utilise des URLs relatives dans les types de média basés sur xml et ça marche bien. Soyez prudent avec les slips à la fin parce que l'URL relative "1" est différente si l'URL de base est "http: // localhost/API/Personnes" ou "http: // localhost/API/Personnes /" J'utilise un XML: base attribuer pour éviter la confusion. Pour répondre partiellement à la question de Troelskn. Je trouve que l'URL relative est plus simple à générer du côté serveur. –

1

Semble REST-cool. Même j'ai travaillé sur le même genre de choses, quelques jours plus tôt.

Le seul changement, j'aimerais faire, c'est le lien direct vers les détails de la personne. Et aussi quelques détails (comme nom ici) pour identifier la personne, et m'aider dans la décision de naviguer plus loin. Comme ...

{ 
    "persons": 
    [ 
    { "name": "John Smith", "href": "http://localhost/api/persons/1/" }, 
    { "name": "Mark Henry", "href": "http://localhost/api/persons/2/" }, 
    { "name": "Bruce Wayne", "href": "http://localhost/api/persons/3/" }, 
    ... 
    { "name": "Karl Lewis", "href": "http://localhost/api/persons/100/" } 
    ], 
    "next": "http://localhost/api/persons/?startlat=10&endlat=15&startlng=30&endlng=60&page=2" 
} 

De cette façon, je donne tout, pour présenter des données comme,

Next Page

+2

En fait, à moins que vous incluez les URIs réels dans la réponse, ce n'est pas du tout RESTful. +1 – aehlke

2

Je pense que les paramètres de requête pourraient être plus simples et plus clairs. Cela rendrait l'URI plus lisible et permettrait une plus grande flexibilité pour les futures extensions:

GET http://localhost/api/persons/?latitude=10:15&longitude=30:60 

Vous pouvez activer ces derniers dans l'avenir:

GET http://localhost/api/persons/?latitude=10&longitude=60&within=5km 
0

Il est autorisé à fournir des URIs sténographie dans vos réponses JSON si vous fournissez un système de template. Comme donner un URI de base comme quelque chose comme http://whatever.com/persons/ {id}/et fournir des ID. Ensuite, avec python, vous pouvez simplement faire un appel de format sur la chaîne. Vous ne voulez jamais que le programmeur regarde et comprenne la signification des URI, ce qui n'est pas nécessaire lorsque vous utilisez des templates.

+0

Je veux juste noter qu'il est essentiel que vous fournissiez ce modèle dans le cadre de la réponse, et non dans votre spécification d'API hors-bande. – aehlke

0

Vous pouvez jeter un oeil à middleware REST préexistant. Je sais qu'ils m'ont sauvé beaucoup de temps. J'utilise http://code.google.com/p/django-rest-interface/. Et un extrait du urls.py

json_achievement_resource = Collection(
    queryset = Achievement.objects.all(), 
    permitted_methods = ('GET',), 
    responder = JSONResponder(paginate_by = 10) 
) 

urlpatterns += patterns('', 
    url(r'^api/ach(?:ievement)?/(.*?)/json$', json_achievement_resource), 
) 
Questions connexes