Recomendações da estrutura Python REST (serviços da web)? [fechadas]


321

Existe uma lista de recomendações de diferentes estruturas REST baseadas em Python para uso no servidor para escrever suas próprias APIs RESTful? De preferência com prós e contras.

Por favor, sinta-se livre para adicionar recomendações aqui. :)


Aqui está um bom tutorial sobre o uso de web.py dreamsyssoft.com/blog/blog.php?/archives/…
Triton Man

Respostas:


192

Algo para ter cuidado ao projetar uma API RESTful é a fusão de GET e POST, como se fossem a mesma coisa. É fácil cometer este erro com as visualizações baseadas em funções do Django e o despachante padrão do CherryPy , embora ambas as estruturas agora contornem esse problema ( visualizações baseadas em classe e MethodDispatcher , respectivamente).

Os verbos HTTP são muito importantes no REST e, a menos que você tenha muito cuidado com isso, você acabará caindo em um anti-padrão REST .

Algumas estruturas que acertam são web.py , Flask e Bottle . Quando combinados com a biblioteca mimerender (divulgação completa: escrevi), eles permitem que você escreva bons serviços da web RESTful:

import web
import json
from mimerender import mimerender

render_xml = lambda message: '<message>%s</message>'%message
render_json = lambda **args: json.dumps(args)
render_html = lambda message: '<html><body>%s</body></html>'%message
render_txt = lambda message: message

urls = (
    '/(.*)', 'greet'
)
app = web.application(urls, globals())

class greet:
    @mimerender(
        default = 'html',
        html = render_html,
        xml  = render_xml,
        json = render_json,
        txt  = render_txt
    )
    def GET(self, name):
        if not name: 
            name = 'world'
        return {'message': 'Hello, ' + name + '!'}

if __name__ == "__main__":
    app.run()

A lógica do serviço é implementada apenas uma vez, e a seleção correta da representação (cabeçalho Accept) + expedição para a função de renderização (ou modelo) apropriada é feita de maneira organizada e transparente.

$ curl localhost:8080/x
<html><body>Hello, x!</body></html>

$ curl -H "Accept: application/html" localhost:8080/x
<html><body>Hello, x!</body></html>

$ curl -H "Accept: application/xml" localhost:8080/x
<message>Hello, x!</message>

$ curl -H "Accept: application/json" localhost:8080/x
{'message':'Hello, x!'}

$ curl -H "Accept: text/plain" localhost:8080/x
Hello, x!

Atualização (abril de 2012) : informações adicionadas sobre as visualizações baseadas em classe do Django, os métodos MethodDispatcher da CherryPy e as estruturas Flask and Bottle. Nem existia quando a pergunta foi feita.


12
Isso está incorreto, o Django tem suporte completo para reconhecer POST vs GET e limitar visualizações a apenas determinados métodos.
aehlke 23/07/2009

20
Eu quis dizer que, por padrão, o Django trata POST e GET como se fossem a mesma coisa, o que é muito inconveniente quando você está executando serviços RESTful, pois o força a fazer: if request.method == 'GET': do_something () elif request.method == 'POST': do_something_else () web.py não tem esse problema
Martin Blech

19
@ Wahnfrieden: Se houver suporte nativo no Django para lidar com diferentes verbos HTTP separadamente (por "nativo", quero dizer não precisar "se request.method == X"), você poderia me indicar alguma documentação?
Martin Blech

3
A combinação de POST e GET não se aplica às visualizações baseadas em classe do Django (adicionadas em 1.3), mas acredito que seja válido para os lançamentos anteriores.
Ncoghlan 11/11

1
A resposta está incorreta sobre o CherryPy. Do Docs: "REST (Representational State Transfer) é um estilo de arquitetura adequado para implementação no CherryPy." - docs.cherrypy.org/dev/progguide/REST.html
Derek Litz


23

Estamos usando o Django para serviços web RESTful.

Note que - pronto para uso - o Django não possui autenticação suficientemente refinada para nossas necessidades. Usamos a interface Django-REST , o que ajudou muito. [Desde então, lançamos nossas próprias porque criamos tantas extensões que se tornaram um pesadelo de manutenção.]

Temos dois tipos de URLs: URLs "html", que implementam as páginas HTML orientadas para humanos, e URLs "json", que implementam o processamento orientado a serviços da Web. Nossas funções de visualização geralmente se parecem com isso.

def someUsefulThing( request, object_id ):
    # do some processing
    return { a dictionary with results }

def htmlView( request, object_id ):
    d = someUsefulThing( request, object_id )
    render_to_response( 'template.html', d, ... )

def jsonView( request, object_id ):
    d = someUsefulThing( request, object_id )
    data = serializers.serialize( 'json', d['object'], fields=EXPOSED_FIELDS )
    response = HttpResponse( data, status=200, content_type='application/json' )
    response['Location']= reverse( 'some.path.to.this.view', kwargs={...} )
    return response

O ponto é que a funcionalidade útil é fatorada nas duas apresentações. A apresentação JSON geralmente é apenas um objeto que foi solicitado. A apresentação em HTML geralmente inclui todos os tipos de auxílios à navegação e outras dicas contextuais que ajudam as pessoas a serem produtivas.

As jsonViewfunções são todas muito semelhantes, o que pode ser um pouco irritante. Mas é Python, então faça parte de uma classe que pode ser chamada ou escreva decoradores, se isso ajudar.


2
Repetição terrível de d = someUsefulThing ... Até os caras do Django sugerem DRY.
temoto

5
@temoto: Se y = someUsefulThing(...)é uma "repetição terrível", todas as referências a todas as funções e métodos são "terríveis". Não consigo entender como evitar fazer referência a uma função mais de uma vez.
S.Lott 12/07

5
@temoto: "Quando você precisa alterar os argumentos passados ​​para someUsefulThing, há uma chance de que você se esqueça de fazer isso em todas as chamadas"? O que? Como isso é "horrível"? Essa é uma consequência trivial de referenciar uma função mais de uma vez. Não estou conseguindo entender do que você está falando e como a referência de função é "péssima", pois é inevitável.
31510 S.Lott

4
Veja a resposta aceita. A expressão do resultado {'message': 'Hello,' + name + '!'} É escrita uma vez para todas as apresentações.
temoto 12/07/10

3
Suas funções htmlView e jsonView servem representações diferentes para os mesmos dados, certo? O mesmo someUsefulThing(request, object_id)vale para uma expressão de recuperação de dados. Agora você tem duas cópias da mesma expressão em pontos diferentes do seu programa. Na resposta aceita, a expressão de dados é escrita uma vez. Substitua sua someUsefulThingchamada por uma sequência longa, curta paginate(request, Post.objects.filter(deleted=False, owner=request.user).order_by('comment_count'))e veja o código. Espero que ilustre meu argumento.
temoto


8

Eu realmente gosto de CherryPy . Aqui está um exemplo de um serviço da Web repousante:

import cherrypy
from cherrypy import expose

class Converter:
    @expose
    def index(self):
        return "Hello World!"

    @expose
    def fahr_to_celc(self, degrees):
        temp = (float(degrees) - 32) * 5 / 9
        return "%.01f" % temp

    @expose
    def celc_to_fahr(self, degrees):
        temp = float(degrees) * 9 / 5 + 32
        return "%.01f" % temp

cherrypy.quickstart(Converter())

Isso enfatiza o que eu realmente gosto no CherryPy; este é um exemplo completamente funcional que é muito compreensível até para alguém que não conhece a estrutura. Se você executar esse código, poderá ver imediatamente os resultados no seu navegador da web; por exemplo, visitando http: // localhost: 8080 / celc_to_fahr? degrees = 50 será exibido 122.0no seu navegador.


35
Esse é um bom exemplo, mas não há nada de RESTful nisso.
aehlke 23/07/2009

3
@Wahnfrieden: Você poderia ajudar o resto de nós esclarecendo por que você não acha que o que foi dito acima é RESTful? Do meu ponto de vista, parece um exemplo clássico de REST e não parece quebrar nenhuma das regras ou restrições de um sistema RESTful.
lilbyrdie

42
Em termos simples, o que o exemplo CherryPy acima está fazendo é expor métodos como procedimentos remotos "HTTP". Isso é RPC. É inteiramente "verbo" orientado. As arquiteturas RESTful concentram-se nos recursos gerenciados por um servidor e, em seguida, oferecem um conjunto muito limitado de operações nesses recursos: especificamente, POST (criar), GET (ler), PUT (atualizar) e DELETE (excluir). A manipulação desses recursos, em particular a mudança de estado via PUT, é o principal caminho pelo qual "as coisas acontecem".
verveguy

2
Você pode escrever mais APIs RESTfull usando CherryPy docs.cherrypy.org/stable/progguide/REST.html
Radian


8

Não vejo motivo para usar o Django apenas para expor uma API REST, existem soluções mais leves e flexíveis. O Django carrega muitas outras coisas para a mesa, que nem sempre são necessárias. Com certeza não é necessário se você deseja apenas expor algum código como um serviço REST.

Minha experiência pessoal, fwiw, é que, depois de ter uma estrutura única, você começará a usar seu ORM, seus plugins etc. apenas porque é fácil, e em pouco tempo você acaba tendo uma dependência isso é muito difícil de se livrar.

Escolher uma estrutura da web é uma decisão difícil, e eu evitaria escolher uma solução de pilha cheia apenas para expor uma API REST.

Agora, se você realmente precisa / deseja usar o Django, o Piston é uma boa estrutura REST para aplicativos de django.

Dito isto, o CherryPy também parece muito bom, mas parece mais RPC do que REST.

Olhando para as amostras (eu nunca a usei), provavelmente o web.py é o melhor e mais limpo se você precisar apenas de REST.


6

Aqui está uma discussão nos documentos CherryPy sobre o REST: http://docs.cherrypy.org/dev/progguide/REST.html

Em particular, ele menciona um distribuidor CherryPy incorporado chamado MethodDispatcher, que chama métodos com base em seus identificadores de verbo HTTP (GET, POST, etc ...).


6

Em 2010, as comunidades Pylons e repoze.bfg "uniram forças" para criar o Pyramid , uma estrutura da Web baseada mais fortemente em repoze.bfg. Ele mantém as filosofias de suas estruturas pai e pode ser usado para serviços RESTful . Vale a pena dar uma olhada.


Com o Pyramid, você pode usar o Cornice , que fornece auxiliares úteis para criar e documentar serviços da Web REST.
Calvin


5

Parece que todos os tipos de estruturas da web python podem implementar interfaces RESTful agora.

Para o Django, além de tastypie e piston, o django-rest-framework é promissor e vale a pena mencionar. Já migrei um dos meus projetos para ele sem problemas.

A estrutura REST do Django é uma estrutura REST leve para o Django, que visa facilitar a criação de APIs da Web RESTful bem conectadas e autoexplicativas.

Exemplo rápido:

from django.conf.urls.defaults import patterns, url
from djangorestframework.resources import ModelResource
from djangorestframework.views import ListOrCreateModelView, InstanceModelView
from myapp.models import MyModel

class MyResource(ModelResource):
    model = MyModel

urlpatterns = patterns('',
    url(r'^$', ListOrCreateModelView.as_view(resource=MyResource)),
    url(r'^(?P<pk>[^/]+)/$', InstanceModelView.as_view(resource=MyResource)),
)

Pegue o exemplo do site oficial, todos os códigos acima fornecem API, documento autoexplicado (como webservice baseado em sabão) e até caixa de areia para testar um pouco. Muito conveniência.

Links: http://django-rest-framework.org/


2
Especialmente a interface testável economiza muito tempo durante o desenvolvimento! Muitas outras vantagens, portanto, todos que estão iniciando a implementação do resto devem dar uma olhada. Comecei com tastypie, mas mudou completamente a django-resto-quadro
michel.iamit

3

Não sou especialista no mundo python, mas tenho usado o django, que é um excelente framework para web e pode ser usado para criar um framework repousante.


3

web2py inclui suporte para a criação fácil de APIs RESTful, descritas aqui e aqui (vídeo). Em particular, observe parse_as_rest, que permite definir padrões de URL que mapeiam argumentos de solicitação para consultas de banco de dados; e smart_query, que permite que você passe consultas arbitrárias em linguagem natural no URL.


Os links mencionados não estão mais disponíveis
milovanderlinden

Os links foram atualizados - tente novamente.
Anthony


0

Eu recomendo TurboGears ou Bottle:

TurboGears:

  • menos detalhado que django
  • mais flexível, menos orientado a HTML
  • mas: menos famoso

Garrafa:

  • muito rápido
  • muito fácil de aprender
  • mas: minimalista e não maduro

0

Estamos trabalhando em uma estrutura para serviços REST rigorosos, confira http://prestans.googlecode.com

No início do Alpha, no momento, estamos testando o mod_wsgi e o AppEngine do Google.

Procurando testadores e feedback. Obrigado.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.