Когда и где агрегировать или выполнять вычисления для данных в RESTful Rails API - PullRequest
1 голос
/ 25 июня 2019

Мне было интересно, существует ли общий способ объединения данных или выполнения вычислений на них (например, захват десяти случайных строк сценария фильма или умножение десяти цен на продукты друг на друга) в Rails или в MVC в целом,В частности, я пытаюсь сделать первый пример (10 строк сценария фильма) в моем приложении.

Я использую Rails 5.2+.То, что я до сих пор пробовал, это создание метода экземпляра getRandomLines в моем ScriptLinesController.Но я не уверен, должен ли я вместо этого использовать метод show и агрегировать данные на стороне клиента, или мне следует поместить метод в модель ScriptLine

Я протестировал следующееМаршрут с использованием Почтальона, и он работает, но кажется, что это неправильный путь:

#My routes.rb:
Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html

  get 'script_lines/test', to: 'script_lines#getRandomLines'

end

Мой контроллер выглядит так:

class ScriptLinesController < ApplicationController
  def index
    render json: ScriptLine.all
  end

  def show
    scriptLine = ScriptLine.find_by(id: params[:id])

    render json: scriptLine
  end

  def getRandomLines
    numLines=rand(0..9)
    nineLines = []
    numLines.times do
      id_num = rand(1..ScriptLine.last.id)
      nineLines << ScriptLine.find_by(id: id_num)
    end

    render json: nineLines[0]
  end
end

Моя модель выглядит так:

class ScriptLine < ApplicationRecord
  validates :line_number, presence:true

  belongs_to :script
end

Наконец, моя схема выглядит следующим образом:

  create_table "script_lines", force: :cascade do |t|
    t.string "line_number"
    t.string "line"
    t.bigint "script_id"
    t.index ["script_id"], name: "index_script_lines_on_script_id"
  end

Итак, в общем, создание методов в контроллере и указание маршрутов к этим методам - ​​правильный способ агрегировать / выполнять вычисления на данных.в остальном?В частности, мне интересно, являются ли разрешенными только 7 стандартных маршрутов RESTful, или если у вас могут быть специальные маршруты для манипулирования данными, которые соответствуют принципам REST.

Это мой первый вопрос, поэтому заранее извиняюсь, если он задает слишком много или слишком расплывчато, изменится соответственно.

1 Ответ

3 голосов
/ 25 июня 2019

Это довольно широкий вопрос о дизайне, поэтому я просто приведу список общих указателей для размышления:

  • Важным компонентом дизайна веб-сервиса RESTful является выбор правильных ресурсов, которые не должны напрямую соответствовать таблицам в вашей базе данных. Вполне уместно изобретать новые ресурсы (обычно, но теперь всегда с соответствующим классом в models/), которые более естественно отображают то, что ищет клиент.
  • В общем, я бы рекомендовал выполнять агрегирование на стороне сервера на уровне базы данных (или с помощью какого-либо другого механизма хранения данных, например, предварительно вычисленного кэша, если даже база данных работает слишком медленно)
  • Если вы используете реляционную базу данных, может быть полезно определить представления, которые выполняют агрегирование (https://www.postgresql.org/docs/11/sql-createview.html). Затем вы можете создать модель activerecord, которая ссылается на представление
  • Как правило, не стоит создавать методы контроллера, имена которых отличаются от имен в вашем файле маршрутов. В вашем примере у меня будет просто новое действие random на /script_lines/random, а затем метод контроллера random.
  • В зависимости от того, насколько действительно «RESTful» вы хотите быть, вам может понадобиться или не работать в кодовой базе, где допустимо определять нестандартные действия контроллера, и это может или не может быть приемлемо для возврата конечной точки GET. случайные результаты, подобные этому (оба из них могут нарушить строгое определение REST). Проверьте этот ответ: Веб-сервис RESTful для получения глагола случайного числа для дополнительного контекста.

Лично, если бы я не был чрезмерно обеспокоен RESTful-ностью, я бы добавил новое действие в ScriptLinesController, например:

class ScriptLinesController < ApplicationController
  def random
    num_lines = rand(0..9)
    render json: ScriptLine.order("RANDOM()").limit(num_lines)
  end
end

Поскольку функция random со временем усложнялась, я бы подумал о ее перемещении в модель ScriptLine. Если добавится еще больше сложностей, которые логически связаны с понятием «Коллекция случайных строк сценария», я перенесу этот код в отдельную другую модель и создам новый контроллер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...