Ответ 1
Вы делаете две ошибки.
Во-первых, Flask-RESTful заставляет вас думать, что ресурс реализован с одним URL-адресом. На самом деле у вас может быть много разных URL-адресов, которые возвращают ресурсы того же типа. В Flask-RESTful вам понадобится создать другой подкласс Resource
для каждого URL-адреса, но концептуально эти URL-адреса принадлежат одному и тому же ресурсу. Обратите внимание: вы фактически создали два экземпляра на ресурс для обработки списка и отдельных запросов.
Вторая ошибка, которую вы делаете, заключается в том, что вы ожидаете, что клиент узнает все URL-адреса вашего API. Это не очень хороший способ для создания API, в идеале клиент знает только несколько URL верхнего уровня, а затем обнаруживает остальное от данных в ответах от верхнего уровня.
В вашем API вы можете открыть /api/users
и /api/cities
как API верхнего уровня. URL-адреса для отдельных городов и пользователей будут включены в ответы. Например, если я вызываю http://example.com/api/users
, чтобы получить список пользователей, я могу получить этот ответ:
{
"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-адрес города. Клиенту не нужно знать, как их создавать, потому что они ему предоставляются.
Получение городов по их имени
URL для города /api/city/<id>
, а URL для получения полного списка городов - /api/cities
, как вы его определили.
Если вам также нужно искать города по их имени, вы можете расширить конечную точку "городов", чтобы сделать это. Например, вы могли бы иметь URL-адреса в форме /api/cities/<name>
, чтобы вернуть список городов, которые соответствуют поисковому запросу, указанному как <name>
.
С помощью Flask-RESTful вам нужно будет определить новый подкласс Resource
для этого, например:
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:
{
"url": "http://example.com/api/city/35",
"name": "San Francisco",
"users": "http://example/com/api/city/35/users"
}
Теперь у меня есть город, и это дало мне URL-адрес, который я могу использовать, чтобы получить всех пользователей в этом городе.
Обратите внимание, что не имеет значения, что ваши URL-адреса уродливы или сложны в построении, потому что клиенту никогда не нужно создавать большинство из них с нуля, он просто получает их с сервера. Это также позволяет вам изменить формат URL-адресов в будущем.
Чтобы внедрить URL-адрес, который получает пользователей по городу, вы добавляете еще один подкласс Resource
:
class UsersByCityAPI(Resource):
def __init__(self):
# ...
def get(self, id):
# ...
api.add_resource(UsersByCityAPI, '/api/cities/<int:id>/users', endpoint = 'users_by_city')
Надеюсь, это поможет!