Обновление атрибута в запросе на получение?

avatar
Daniel
8 августа 2021 в 18:11
25
1
-1

У меня возникла ситуация, когда я хотел бы обновить атрибут, когда некая третья сторона извлекает данные из конечной точки моего API.

В настоящее время я настроил это следующим образом

module Api
  module V1
    class ListingsController < ApplicationController    
    http_basic_authenticate_with name: "third_party_user", password: "secret", except: :index
    before_action :update_status, only: [:publishable_listings]
    def publishable_listings
     @listings = Listings.where(to_publish: true)
    end 

    private

    def update_status
     listings = Listings.where(to_publish: true).update_all(published: true)
    end 
  end
 end
end

и это всего лишь маршрут

...
get 'publishable_listings' => "listings#publishable_listings"
...

Считается ли это плохой практикой или может существовать альтернативный способ добиться этого?

В основном это предполагает, что единственные GET запросы, поступающие в publishable_listings, будут исходить от third_party_user, и если кто-либо еще сможет сделать GET, это будет проблематично, так как это обновит запись без фактической публикации. .

Источник

Ответы (1)

avatar
Christian Bruckmayer
10 августа 2021 в 02:51
1

Я думаю, что этот вопрос лучше вписывается в https://codereview.stackexchange.com/tags/ruby.

Считается ли это плохой практикой или может существовать альтернативный способ добиться этого?

В принципе, это предполагает, что единственные запросы GET, поступающие в publishable_listings, будут исходить от третьего_участника_пользователя, и если кто-либо еще сможет сделать GET, это будет проблематично, поскольку он обновит запись без фактической публикации.

В вашей текущей архитектуре используется базовая аутентификация, и я не вижу другого способа реализовать это. Предполагая, что только ваша третья сторона когда-либо узнает пароль, это может быть нормально.

Однако, если вы введете понятие пользователя, вы сможете пометить публикацию для пользователя только как опубликованную/прочитанную. Вы можете реализовать это с отношением "многие ко многим".

Другим способом реализации этого может быть простое разбиение на страницы на основе курсора и сохранение последнего курсора в вашем клиенте. Таким образом, ваш клиент может вернуться назад, и его будет легче отлаживать и анализировать.

https://slack.engineering/evolving-api-pagination-at-slack/

Еще несколько советов

Чтобы контроллер был простым, в нем должны быть только основные методы REST (индексировать, показывать, создавать, создавать, редактировать, обновлять, удалять). В вашем случае у вас может быть PublishableListingsController с методом show вместо ListingsController с publishable_listings.

Для получения дополнительной информации см. эту замечательную статью http://jeromedalbert.com/how-dhh-organizes-his-rails-controllers/.

Кроме того, присвоение listings здесь на самом деле не используется, и я бы рекомендовал делать это не перед действием, потому что, если ваш второй запрос завершится ошибкой, вы получите список, который уже помечен как опубликованный, но никогда не фактически получено.

def update_status
  listings = Listings.where(to_publish: true).update_all(published: true)
end 

В идеале вы хотите сделать это за одну операцию или транзакцию.

def show
  @listings = Listings.where(to_publish: true)
  @listing.update_all(published: true)
end