6

Flask-RESTful を使用して API を開発しており、アプリケーションには 3 つの役割があります。

  1. サイト管理者
  2. 部門_管理者
  3. 基本

特定のリソースについて、返される JSON オブジェクトには、各ロールに基づいた異なるキー セットがあります。

たとえば、「site_admin」として /orders をヒットすると、結果は次のようになります。

{
  "orders": [
    {"id": 1, "user": "foo", "paid": True,  "department": "A", "code": 456},
    {"id": 2, "user": "bar", "paid": False, "department": "A", "code": 567},
    {"id": 3, "user": "meh", "paid": False, "department": "B", "code": 678}
  ]
}

ただし、「department_admin」として /orders をヒットすると、結果は次のようになります。

{
  "orders": [
    {"id": 3, "user": "meh", "paid": False}
  ]
}

/orders を「basic」としてヒットすると、次のような非常に最小限の JSON 応答になります。

{
  "orders": [
    {"id": 2, "paid": True}
  ]
}

これを実装するRESTfulな方法は何ですか?

3つの方法を思い付くことができます。

(1) リクエスト引数を使用し、それをフィルタリングする:

class Orders(restful.Resource):
  def get(self):
    if request.args['role'] == 'site_admin':
      return admin_JSON_response()
    elif request.args['role'] == 'department_admin':
      return dept_admin_JSON_response()
    else:
      return basic_JSON_response()

api.add_resource(Orders, '/orders')

(2) セッション オブジェクトのフィルタリング:

class Orders(restful.Resource):
  def get(self):
    if session['role'] == 'site_admin':
      return admin_JSON_response()
    elif session['role'] == 'department_admin':
      return dept_admin_JSON_response()
    else:
      return basic_JSON_response()

api.add_resource(Orders, '/orders')

(3) 役割ごとに異なるルートを持つ:

class OrdersSiteAdmin(restful.Resource):
  def get(self):
    return admin_JSON_response()
api.add_resource(OrdersSiteAdmin, '/orders_site_admin')

class OrdersDeptAdmin(restful.Resource):
  def get(self):
    return dept_admin_JSON_response()
api.add_resource(OrdersDeptAdmin, '/orders_dept_admin')

class OrdersBasic(restful.Resource):
  def get(self):
      return basic_JSON_response()
api.add_resource(OrdersBasic, '/orders_basic')

... どちらが RESTful な方法として好まれるかについてコンセンサスはありますか?

本当にありがとう!

4

1 に答える 1

4

オプション #2 は「ステートレス」制約に違反しています。REST API でユーザー セッションを使用することはお勧めできません。代わりに、クライアントにすべてのリクエストで認証を提供するよう要求する必要があります。

#2 を修正し、ユーザー セッションの代わりに、current_user認証中に入力される変数があるとします。次に、その例を次のように書き直すことができます。

class Orders(restful.Resource):
  def get(self):
    if current_user.role == 'site_admin':
      return admin_JSON_response()
    elif current_user.role == 'department_admin':
      return dept_admin_JSON_response()
    else:
      return basic_JSON_response()

api.add_resource(Orders, '/orders')

3 つのオプションを 1 つずつ見てみましょう。

  • (1) クエリ文字列で役割を指定します。これにより、目的の役割を渡すだけで、任意のユーザーが任意の表現を要求できるようになります。しかし、なぜロールをクエリ文字列に入れるのでしょうか? ユーザーを認証することを想定しているため、ユーザーを知っていれば役割も知っています。これは不要なようで、追加の検証作業が必要になります。

  • (3) ロールごとに異なるリソースを作成します。繰り返しますが、「基本」ユーザーが、より高い役割に適用される 2 つの URL にアクセスできないようにする必要があるため、ここでもいくつかの検証作業が必要です。

  • (2) ユーザー データベースに各ユーザーの役割が格納されていると想定しているため、ユーザーが認証されると、割り当てられた役割に基づいて、その役割の正しい表現が返されます。これは、ユーザーが見ることを許可されていないデータにハッキングする方法が実際にないため、最良のオプションだと思います。

RESTful であると言えば、改善できる表現も検討します。HATEOAS制約に準拠するために、ID を提供する代わりに他のリソースへのリンクを実装することを検討してください。

于 2014-12-02T22:04:13.600 に答える