grape-jsonapi icon indicating copy to clipboard operation
grape-jsonapi copied to clipboard

Passing is_array to grape swagger doesn't work as expected

Open code-bunny opened this issue 6 months ago • 1 comments

desc "Transactions" do
  success ::Frontend::TransactionSerializer
  is_array true
  produces [ "application/vnd.api+json" ]
  consumes [ "application/vnd.api+json" ]
  headers Authorization: {
    description: "Authorization token for the current user(JWT).",
    required: true
  }
end

With the included desc block we are passing is_array so our FE team can generate their code from our swagger docs. However, this is not working as expected as it just wraps the whole document in an array instead of data: [] we get [data: {}]. Which is obviously undesired. Is there some other method we are missing that we'd need to call?

code-bunny avatar May 20 '25 10:05 code-bunny

It's inelegant but I came up with the following:

module GrapeSwagger
  module Jsonapi
    class CollectionParser
      attr_reader :wrapper
      attr_reader :endpoint

      def initialize(wrapper, endpoint)
        @wrapper = wrapper
        @endpoint = endpoint
      end

      def call
        single_resource_schema = Parser.new(wrapper.model, endpoint).call[:data]

        {
          wrapper.key => {
            type: :array,
            items: single_resource_schema
          }
        }
      end
    end
  end
end

module GrapeSwagger
  module Jsonapi
    class Collection
      attr_reader :model
      attr_reader :key
      attr_reader :wrapper_name

      def initialize(model, wrapper_name: nil, key: :data)
        @model = model
        @wrapper_name = wrapper_name
        @key = key
      end

      def ancestors
        [Collection]
      end

      def to_s
        wrapper_name ? wrapper_name : "data_wrapper_#{object_id}"
      end
    end
  end
end

require "grape_swagger/jsonapi/parser"
require "grape_swagger/jsonapi/collection"
require "grape_swagger/jsonapi/collection_parser"
require File.join(Rails.root, "app/serializers/base_serializer")

GrapeSwagger.model_parsers.register(GrapeSwagger::Jsonapi::CollectionParser, GrapeSwagger::Jsonapi::Collection)
GrapeSwagger.model_parsers.register(GrapeSwagger::Jsonapi::Parser, BaseSerializer)

desc "Transactions" do
  success code: 200, model: GrapeSwagger::Jsonapi::Collection.new(::Frontend::TransactionSerializer)
  produces [ "application/vnd.api+json" ]
  consumes [ "application/vnd.api+json" ]
  headers Authorization: {
    description: "Authorization token for the current user(JWT).",
    required: true
  }
end

It'd be better if we could just send a is_collection: true. But sadly I don't know how to do that just now.

code-bunny avatar May 20 '25 11:05 code-bunny