Flask - 嵌套的rest api - 使用方法视图以外的东西或者我做了一个糟糕的设计?

Sky*_*and 6 python api rest flask

刚开始使用Flask,请访问http://flask.pocoo.org/docs/views/

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

/
    GET - list
    POST - create

/<symptomid>
    GET - detail
    PUT - replace
    PATCH - patch
    DELETE - delete
Run Code Online (Sandbox Code Playgroud)

我可以用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)
Run Code Online (Sandbox Code Playgroud)

但是,让我们说我想在这些个别症状上附加另一个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
Run Code Online (Sandbox Code Playgroud)

然后我会有4个GET而不是上面的两个.

  1. 你认为这是一个糟糕的api设计吗?
  2. MethodView是适宜的设计?(如果设计不错)
  3. 你会如何实现这些路线?

所以......在写这个问题时,我找到了一个不错的解决方案.只要我在这里,我不妨发布我的问题和解决方案.任何反馈仍然会非常感激.

Sky*_*and 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)
Run Code Online (Sandbox Code Playgroud)