How to define a complex JSON response with Rswag using fast json api serializer

1.1k Views Asked by At

I'm getting rswag setup so I can easily generate documentation for my rails API. I'm already using gem 'jsonapi-serializer' to build the responses and it is working well.

However, I can't seem to figure out how to define the response in the schema section of the rswag definition.

Right now I have this:

# spec/integrations/customer_spec.rb
    get 'Retrieves a customer' do
      tags 'Customers'
      produces 'application/json'
      parameter name: :id, in: :path, type: :string
      security [api_key: []]

      response '200', 'customer found' do
        schema type: :object,
          properties: {
            id: { type: :integer },
            name: { type: :string },
            email: { type: :string },
            address: { type: :json }
          },
          required: [ 'id' ]

          let(:id) { customer.public_id }

        run_test!
      end

I understand how to define simple responses like in the above code sample, but I'm not sure how to define more complex responses.

Here's an example response body:

 "data"=>
  {"data"=>
    {"id"=>"cust_29od5g7d8aPuPXzb3JHfQCpzYjb",
     "type"=>"customer",
     "attributes"=>{"name"=>"Pouros, Zboncak and Bernhard", "phone"=>"+13105552474", "email"=>"[email protected]", "address"=>"13949 Janey Village, Farrellmouth, NH 73307-1612", "stripe_customer_id"=>nil, "permissions"=>{"data"=>[]}},
     "relationships"=>{"subscriptions"=>{"data"=>[]}, "products"=>{"data"=>[]}, "customer_quotas"=>{"data"=>[]}}}}}

Right now, I get this error. I'm not sure how to structure the schema to identify where the id is:

 Rswag::Specs::UnexpectedResponse:
       Expected response body to match schema: The property '#/' did not contain a required property of 'id' in schema 586f23d3-4484-5ad4-ad61-154265f7292b
...
1

There are 1 best solutions below

0
On

I have not developed with that gem before, but that is a JSON schema validation error indicating the response does not match the schema you've defined. Your pasted response is a ruby hash (not JSON) and is missing a brace so it's difficult to know whether you made a mistake while pasting or if your response truly has two nested levels of "data"; if it's not a mistake, then a likely cause for an error like this would be the spec looking for 'id' at a key level where it does not exist (i.e., a level of the hash where the only key is 'data').

The first example the gem provides in their README's Rspec DSL section and your schema definition both indicate it is expecting the response's top level keys to equal the keys defined in the schema's properties (meaning get rid of the top two data levels and it's likely to work). If it's a typo scenario but your response must contain a data root key, then you will need to either adjust your schema or follow the example in the DSL for parsing the JSON + validating the structure in a different way.

I find the Swagger.io docs (e.g., https://swagger.io/docs/specification/describing-responses/, https://swagger.io/docs/specification/data-models/dictionaries/, https://swagger.io/specification/) to be really helpful; they also have some tools, like https://inspector.swagger.io/builder. The API builder features in an API Client tool like Insomnia or Postman can also be really helpful for playing with the OpenAPI syntax to figure what works and what won't.

I also recommend looking through the gem's source code -- specifically for spec files and sample apps; these typically contain syntax and usage examples that you wouldn't find in a README.