многоресурсный GET/search API, реализованный с помощью JSONAPI

Как бы вы реализовали API /search, который мог бы возвращать разные ресурсы с помощью JSONAPI?

GET /search?q=london может, например, вернуть ресурс author для «Джек Лондон» и ресурс book для «Лондон: роман».

Я начал делать это с реализации ресурса search, который возвращал бы включенные ресурсы book и author, но чтобы следовать JSONAPI, мне пришлось бы реорганизовать API до GET /search?filger[q]=london

У меня такое ощущение, что этот (довольно распространенный) вариант использования на самом деле не рассматривался JSONAPI.

Моя конечная цель — реализовать это с помощью бэкенда Rails, используя JSONAPI::Resources и приложение ember с ember-data.

Что бы вы посоветовали?


person bartocc    schedule 14.09.2015    source источник
comment
Я не думаю, что вы сможете использовать ember-data как есть. Скорее всего, вам потребуется создать собственный адаптер для возврата соответствующего типа модели в зависимости от результата с вашего сервера.   -  person QuantumLicht    schedule 14.09.2015
comment
Модель-оболочка, в которой много книг, много авторов и т. д.?   -  person elithrar    schedule 15.09.2015


Ответы (2)


Вы можете сделать это вручную, используя гем jsonapi-utils, чтобы указать нужный ресурс. использовать для сериализации:

Методом jsonapi_serialize:

class SearchesController < BaseController
  def index
    results = MySearchEngine.search(params)
    render json: jsonapi_serialize(results, options: { resource: UserResource })
  end
end

Или высокоуровневый метод jsonapi_render:

class SearchesController < BaseController
  def index
    results = MySearchEngine.search(params)
    jsonapi_render json: results, options: { resource: UserResource }
  end
end

Надеюсь, поможет.

person Tiago G.    schedule 29.12.2015

Вот что я сделал:

# config/routes.rb
resource :search, only: [:show]

# app/controllers/searches_controller.rb
def show
  render json: Search.new(params).as_json
end

# app/classes/search.rb
class Search
  def initialize(params = {})
    @results = [
      Author.where(name: params[:q]),
      Book.where(title: params[:q]),
    ].flatten
  end

  def as_json
    serialized_resources =
      @results.map do |result|
        resource = JSONAPI::Resource.resource_for(result.model_name.singular)
        serializer = JSONAPI::ResourceSerializer.new(resource)
        serializer.serialize_to_hash(resource.new(result, nil))[:data]
      end
    { data: serialized_resources }
  end
end

Конечно, есть лучший способ?

person eremite    schedule 25.05.2016