#ruby-on-rails
#ruby-on-rails
Вопрос:
У меня есть приложение rails с некоторыми стандартными маршрутами, и я хотел бы добавить в него некоторые конечные точки API.
Я полагаю, мне просто нужно добавить несколько маршрутов (возможно, под scope '/api'
), создать несколько новых контроллеров, которые расширяются ActionController::API
, а затем, возможно, сделать что-то, чтобы rails волшебным образом знал, как отображать данные JSON.
Есть ли какие-либо руководства о том, как это сделать? Все, что я могу найти, говорит о создании приложений «только для API», но не обсуждает добавление нескольких конечных точек API в существующее веб-приложение.
редактировать: я специально ищу решения rails 5
Комментарии:
1. Как, черт возьми, у этого есть только 316 просмотров и ранее 0 голосов? Поражает меня. Такой хороший и широко применимый вопрос.
Ответ №1:
Разница между «классическим» приложением или приложением только с API довольно мала. Приложение, предназначенное только для API, масштабирует часть промежуточного программного обеспечения и компонентов, которые не нужны в API.
В остальном этапы создания реальных компонентов API практически идентичны.
Вы захотите начать с выбора другого суперкласса для ваших контроллеров API. Вашим контроллерам API не нужен весь мусор в ApplicationController, и вы будете по-другому относиться к нескольким аспектам, таким как аутентификация.
В Rails 5 есть ActionController::API
, в предыдущих версиях вы бы использовали ActionController::Metal
и включали необходимые модули.
# app/controllers/api_controller.rb
class ApiController < ActionController::API
# Do whatever you would do in ApplicationController
end
Затем вы настраиваете свои маршруты:
namespace :api, defaults: { format: :json } do
resources :things
end
И контроллеры:
module API
class ThingsController < ApiController
before_action :set_thing, except: [:create, :index]
def show
render json: @thing
end
def index
render json: @things = Thing.all
end
def create
@thing = Thing.create(thing_params)
if @thing.save
head :created, location: [:api, @thing]
else
render json: @thing.errors, status: :bad_entity
end
end
# ...
end
end
Существует довольно много аспектов создания API, таких как управление версиями и стратегии сериализации JSON, и вы найдете множество руководств по этому вопросу — просто не зацикливайтесь только на части API.
Комментарии:
1. как
ApiController
вышеуказанное сочетается с моим существующимApplicationController
? Как rails узнает, что на это нужно смотреть? редактировать: это из-заnamespace
?2. Потому что вы настроили свои контроллеры API на наследование от ApiController вместо ApplicationController. В ApplicationController в Rails нет ничего волшебного. Это просто класс, от которого генераторы rails настраивают контроллеры для наследования. Я понимаю, что забыл добавить
< ApiController
в примере — надеюсь, теперь это более понятно.3. о, вау, я вижу, я думаю, что, возможно, это была недостающая часть… Сейчас я на своем телефоне, но вернусь к этому позже сегодня и закрою это, спасибо!
Ответ №2:
- Выберите формат данных API (в данном случае мы будем использовать JSON)
- Выясните, какими будут ваши конечные точки (например, предположим, что вы создаете
products#create
конечную точку) - Определите область видимости API и схему управления версиями (в данном случае
v1
) - В вашем
config/routes.rb
добавьте маршруты, показанные ниже - Создайте каталог в каталоге вашего контроллера с именем
v1
-
Создайте контроллер в этом
v1
каталоге, подобном приведенному ниже#goes in routes namespace 'v1', defaults: {format: 'json'} do resources :products, only: [:create] end #controller module V1 class ProductsController < ActionController::API def create #some code end end end
Случайные мудрости
- Постарайтесь как можно тщательнее продумать свою конечную точку. Я не знаю, планируете ли вы, чтобы кто-то использовал этот API, или вы будете единственным человеком, использующим его, но подумайте о каждой конечной точке с точки зрения того, что будет ее использовать; это сэкономит вам много времени на рефакторинг и редизайн.
- Вы также должны изучить схему использования сериализаторов, чтобы помочь вам в оформлении объектов, прежде чем отправлять их своим конечным точкам.
- Убедитесь, что вы подумали о том, как вы хотите обрабатывать ошибки, хотите ли вы, чтобы они завершались беззвучно, хотите ли вы возвращать информацию потребителю и т.д. Что бы вы ни решили сделать, просто убедитесь, что вы последовательны.
Посмотрите здесь, чтобы получить несколько советов:
https://www.codementor.io/franzejr/creating-simple-api-with-rails-du108148l
https://www.airpair.com/ruby-on-rails/posts/building-a-restful-api-in-a-rails-application
Комментарии:
1. Это не дает ответа на вопрос. Это просто какие-то случайные мудрости.
2. Привет, спасибо, но, похоже, они предназначены для rails 4 (или, по крайней мере, меньше, чем rails 5) и фактически не касаются добавления API в существующее приложение
3. Да, я активно редактирую, извините, что комментария rails 5 не было, когда я начал отвечать.
4. просто чтобы уточнить, я не знаю конкретных шагов, чтобы сделать так, чтобы контроллер возвращал данные JSON — я получаю маршруты, и я предполагаю, что могу создать контроллер, перейдя
rails g controller my_thing
и вручную изменив базовый класс наActionController::API
, но как добавить действие, которое возвращает данные JSON?5. (Я концептуально знаю, что такое API и как его спроектировать, но не знаю, как создать его в моем существующем приложении rails)
Ответ №3:
используйте что-то вроде
namespace :api, defaults: {format: 'json'} do
чтобы ваши контроллеры API по умолчанию отображали только json.
остальное из того, что вы описали, является достойной реализацией и является именно тем, что мы используем в производстве сегодня. некоторые конечные точки по-прежнему являются обычными rails, но большинство из них являются api json только с MVC на стороне клиента, выполняющим тяжелую работу. это распространенный вариант использования при переходе с приложений rails по умолчанию на MVC на стороне клиента.
еще один полезный совет — использовать в своих контроллерах API созданный вами базовый контроллер API, который наследуется от application controller.