Flask RESTful API多个复杂端点 [英] Flask RESTful API multiple and complex endpoints

查看:76
本文介绍了Flask RESTful API多个复杂端点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Flask-RESTful API中,假设我有两个对象,用户和城市.这是一对多关系.现在,当我创建我的API并向其中添加资源时,我似乎可以做的就是将非常简单的通用URL映射到它们.这是代码(不包括无用的东西):

In my Flask-RESTful API, imagine I have two objects, users and cities. It is a 1-to-many relationship. Now when I create my API and add resources to it, all I can seem to do is map very easy and general URLs to them. Here is the code (with useless stuff not included):

class UserAPI(Resource):  # The API class that handles a single user
  def __init__(self):
    # Initialize

  def get(self, id):
    # GET requests

  def put(self, id):
    # PUT requests

  def delete(self, id):
    # DELETE requests

class UserListAPI(Resource):  # The API class that handles the whole group of Users
  def __init__(self):

  def get(self):

  def post(self):

api.add_resource(UserAPI, '/api/user/<int:id>', endpoint='user')
api.add_resource(UserListAPI, '/api/users/', endpoint='users')

class CityAPI(Resource):
  def __init__(self):

  def get(self, id):

  def put(self, id):

  def delete(self, id):

class CityListAPI(Resource):
  def __init__(self):

  def get(self):

  def post(self):

api.add_resource(CityListAPI, '/api/cities/', endpoint='cities')
api.add_resource(CityAPI, '/api/city/<int:id>', endpoint='city')

如您所见,我可以做我想实现非常基本的功能的所有事情.我可以获取,发布,放置和删除两个对象.但是,我的目标是双重的:

As you can see, I can do everything I want to implement very basic functionality. I can get, post, put, and delete both objects. However, my goal is two-fold:

(1)能够使用其他参数(例如城市名称)进行请求,而不仅仅是 城市编号.看起来像这样:
api.add_resource(CityAPI, '/api/city/<string:name>', endpoint='city')
除非它不会抛出此错误:

(1) To be able to request with other parameters like city name instead of just city id. It would look something like:
api.add_resource(CityAPI, '/api/city/<string:name>', endpoint='city')
except it wouldn't throw me this error:

AssertionError:视图函数映射正在覆盖现有的 端点函数

AssertionError: View function mapping is overwriting an existing endpoint function

(2)能够将两个资源合并到一个请求中.说我想得到所有 与某个城市关联的用户.在REST URL中,其外观应类似于:
/api/cities/<int:id>/users

(2) To be able to combine the two Resources in a Request. Say I wanted to get all the users associated with some city. In REST URLs, it should look something like:
/api/cities/<int:id>/users

我如何用Flask来做到这一点?我将其映射到哪个端点?

How do I do that with Flask? What endpoint do I map it to?

基本上,我正在寻找使API从基本变为可用的方法.感谢您的任何想法/建议

Basically, I'm looking for ways to take my API from basic to useable. Thanks for any ideas/advice

推荐答案

您正在犯两个错误.

首先,Flask-RESTful使您认为资源是通过单个URL实施的.实际上,您可以有许多不同的URL返回相同类型的资源.在Flask-RESTful中,您将需要为每个URL创建一个不同的Resource子类,但是从概念上讲,这些URL属于同一资源.请注意,实际上,您已经为每个资源创建了两个实例来处理列表和单个请求.

First, Flask-RESTful leads you to think that a resource is implemented with a single URL. In reality, you can have many different URLs that return resources of the same type. In Flask-RESTful you will need to create a different Resource subclass for each URL, but conceptually those URLs belong to the same resource. Note that you have, in fact, created two instances per resource already to handle the list and the individual requests.

您犯的第二个错误是您希望客户端知道您API中的所有URL.这不是构建API的好方法,理想情况下,客户端只知道一些顶级URL,然后再从顶级URL的响应中发现数据.

The second mistake that you are making is that you expect the client to know all the URLs in your API. This is not a good way to build APIs, ideally the client only knows a few top-level URLs and then discovers the rest from data in the responses from the top-level ones.

在您的API中,您可能希望将/api/users/api/cities公开为顶级API.指向各个城市和用户的URL将包含在响应中.例如,如果我调用http://example.com/api/users来获取用户列表,我可能会收到以下响应:

In your API you may want to expose the /api/users and /api/cities as top-level APIs. The URLs to individual cities and users will be included in the responses. For example, if I invoke http://example.com/api/users to get the list of users I may get this response:

{
    "users": [ 
        {
            "url": "http://example.com/api/user/1",
            "name": "John Smith",
            "city": "http://example.com/api/city/35"
        },
        {
            "url": "http://example.com/api/user/2",
            "name": "Susan Jones",
            "city": "http://example.com/api/city/2"
        }
    ]
}

请注意,用户的JSON表示包括该用户的URL以及城市的URL.客户不需要知道如何构建它们,因为它们已经被赋予了它.

Note that the JSON representation of a user includes the URL for that user, and also the URL for the city. The client does not need to know how to build these, because they are given to it.

城市的URL为/api/city/<id>,获取城市完整列表的URL为/api/cities(如您所定义).

The URL for a city is /api/city/<id>, and the URL to get the complete list of cities is /api/cities, as you have it defined.

如果您还需要按城市名称搜索城市,则可以扩展城市"端点来进行.例如,您可以使用/api/cities/<name>形式的URL返回与以<name>给出的搜索词相匹配的城市列表.

If you also need to search for cities by their name you can extend the "cities" endpoint to do that. For example, you could have URLs in the form /api/cities/<name> return the list of cities that match the search term given as <name>.

使用Flask-RESTful,您将需要为此定义一个新的Resource子类,例如:

With Flask-RESTful you will need to define a new Resource subclass for that, for example:

    class CitiesByNameAPI(Resource):
        def __init__(self):
            # ...    
        def get(self, name):
            # ...

    api.add_resource(CitiesByNameAPI, '/api/cities/<name>', endpoint = 'cities_by_name')

获取属于某个城市的所有用户

当客户要求一个城市时,它应该得到一个包含URL的响应,以吸引该城市的用户.例如,假设在上面的/api/users响应中,我想了解第一个用户所在的城市.因此,现在我向http://example/api/city/35发送请求,并返回以下JSON响应:

Getting all the users that belong to a city

When the client asks for a city it should get a response that includes a URL to get the users in that city. For example, let's say that from the /api/users response above I want to find out about the city of the first user. So now I send a request to http://example/api/city/35, and I get back the following JSON response:

{
    "url": "http://example.com/api/city/35",
    "name": "San Francisco",
    "users": "http://example/com/api/city/35/users"
}

现在我有了城市,这给了我一个URL,我可以使用它来获取该城市中的所有用户.

Now I have the city, and that gave me a URL that I can use to get all the users in that city.

请注意,您的URL丑陋或难以构建都没关系,因为客户端永远不需要从头开始构建大多数URL,它只是从服务器获取它们.这也使您将来可以更改URL的格式.

Note that it does not matter that your URLs are ugly or hard to construct, because the client never needs to build most of these from scratch, it just gets them from the server. This also enables you to change the format of the URLs in the future.

要实现按城市吸引用户的网址,您可以添加另一个Resource子类:

To implement the URL that gets users by city you add yet another Resource subclass:

    class UsersByCityAPI(Resource):
        def __init__(self):
            # ...    
        def get(self, id):
            # ...

    api.add_resource(UsersByCityAPI, '/api/cities/<int:id>/users', endpoint = 'users_by_city')

我希望这会有所帮助!

这篇关于Flask RESTful API多个复杂端点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆