6

刚从 Flask 开始,跟着http://flask.pocoo.org/docs/views/

假设我有一个基本的 REST api,在这种情况下用于症状:

/
    GET - list
    POST - create

/<symptomid>
    GET - detail
    PUT - replace
    PATCH - patch
    DELETE - delete

我可以使用 Flask 非常干净地实现这一点MethodView,如下所示:

from flask import Blueprint, request, g
from flask.views import MethodView
#...

mod = Blueprint('api', __name__, url_prefix='/api')

class SymptomAPI(MethodView):
    """ ... """

    url = "/symptoms/"

    def get(self, uid):
        if uid is None:
            return self.list()
        else:
            return self.detail(uid)

    def list(self):
        # ...

    def post(self):
        # ...

    def detail(self, uid):
        # ...

    def put(self, uid):
        # ...

    def patch(self, uid):
        # ...

    def delete(self, uid):
        # ...

    @classmethod
    def register(cls, mod):
        symfunc = cls.as_view("symptom_api")
        mod.add_url_rule(cls.url, defaults={"uid": None}, view_func=symfunc,
                         methods=["GET"])
        mod.add_url_rule(cls.url, view_func=symfunc, methods=["POST"])
        mod.add_url_rule('%s<int:uid>' % cls.url, view_func=symfunc,
                 methods=['GET', 'PUT', 'PATCH', 'DELETE'])


SymptomAPI.register(mod)

但是,假设我想在这些个别症状上附加另一个 api:

/<symptomid>/diagnoses/
    GET - list diags for symptom
    POST - {id: diagid} - create relation with diagnosis

/<symptomid>/diagnoses/<diagnosisid>
    GET - probability symptom given diag
    PUT - update probability of symptom given diag
    DELETE - remove diag - symptom relation

然后我将有 4 个 GET 而不是上面的两个。

  1. 你认为这是一个糟糕的 api 设计吗?
  2. MethodView适合这种设计吗?(如果设计还不错)
  3. 您将如何实施这些路线?

所以......在写这个问题时,我找到了一个不错的解决方案。只要我在这里,我还不如发布我的问题和解决方案。任何反馈仍将不胜感激。

4

1 回答 1

8

我觉得设计还可以。MethodView应该非常棒。您可以像这样将路线放在一起:

class SymptomDiagnosisAPI(MethodView):
    """
    /<symptom_id>/diagnoses/
        GET - list diags for symptoms
        POST - {id: diagid} - create relation with diagnosis

    /<symptom_id>/diagnoses/<diagnosis_id>
        GET - probability symptom given diag
        PUT - update probability of symptom given diag
        DELETE - remove diag - symptom relation
    """

    def get(self, symptom_id, diagnosis_id):
        if diagnosis_id is None:
            return self.list_diagnoses(symptom_id)
        else:
            return self.symptom_diagnosis_detail(symptom_id, diagnosis_id)

    def list_diagnoses(self, symptom_id):
        # ...

    def post(self, symptom_id):
        # ...

    def symptom_diagnosis_detail(self, symptom_id, diagnosis_id):
        # ...    

    def put(self, symptom_id, diagnosis_id):
        # ...    

    def delete(self, symptom_id, diagnosis_id):
        # ...    

    @classmethod
    def register(cls, mod):
        url = "/symptoms/<int:symptom_id>/diagnoses/"
        f = cls.as_view("symptom_diagnosis_api")
        mod.add_url_rule(url, view_func=f, methods=["GET"],
                         defaults={"diagnosis_id": None})
        mod.add_url_rule(url, view_func=f, methods=["POST"])
        mod.add_url_rule('%s<int:diagnosis_id>' % url, view_func=f,
                         methods=['GET', 'PUT', 'DELETE'])

SymptomDiagnosisAPI.register(mod)
于 2012-09-22T05:53:15.077 回答