Skip to content

Commit

Permalink
WIP: Use specs to write an openapi3 spec
Browse files Browse the repository at this point in the history
  • Loading branch information
segiddins committed Jul 1, 2023
1 parent 5ec5af4 commit a9ed0b5
Show file tree
Hide file tree
Showing 7 changed files with 763 additions and 3 deletions.
4 changes: 3 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ gem "clearance", "~> 2.6"
gem "dalli", "~> 3.2"
gem "ddtrace", "~> 1.10", require: "ddtrace/auto_instrument"
gem "dogstatsd-ruby", "~> 5.5"
gem "google-protobuf", "~> 3.22"
gem "google-protobuf", "~> 3.23"
gem "faraday", "~> 1.10"
gem "good_job", "~> 3.14"
gem "gravtastic", "~> 3.2"
Expand Down Expand Up @@ -73,6 +73,7 @@ group :development, :test do
gem "toxiproxy", "~> 2.0"
gem "factory_bot_rails", "~> 6.2"
gem "dotenv-rails", "~> 2.8"
gem "openapi_parser", "~> 1.0"

gem "brakeman", "~> 5.4", require: false
gem "rubocop", "~> 1.48", require: false
Expand All @@ -87,6 +88,7 @@ group :development do
gem "listen", "~> 3.8"
gem "letter_opener", "~> 1.8"
gem "letter_opener_web", "~> 2.0"
gem "rswag-ui", "~> 2.9"
end

group :test do
Expand Down
8 changes: 7 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ GEM
omniauth-rails_csrf_protection (1.0.1)
actionpack (>= 4.2)
omniauth (~> 2.0)
openapi_parser (1.0.0)
opensearch-api (1.0.0)
multi_json
opensearch-dsl (0.2.1)
Expand Down Expand Up @@ -466,6 +467,9 @@ GEM
chunky_png (~> 1.0)
rqrcode_core (~> 1.0)
rqrcode_core (1.2.0)
rswag-ui (2.9.0)
actionpack (>= 3.1, < 7.1)
railties (>= 3.1, < 7.1)
rubocop (1.48.0)
json (~> 2.3)
parallel (~> 1.10)
Expand Down Expand Up @@ -632,7 +636,7 @@ DEPENDENCIES
faraday (~> 1.10)
faraday_middleware-aws-sigv4 (~> 0.6)
good_job (~> 3.14)
google-protobuf (~> 3.22)
google-protobuf (~> 3.23)
gravtastic (~> 3.2)
groupdate (~> 6.2)
high_voltage (~> 3.1)
Expand All @@ -653,6 +657,7 @@ DEPENDENCIES
omniauth (~> 2.1)
omniauth-github (~> 2.0)
omniauth-rails_csrf_protection (~> 1.0)
openapi_parser (~> 1.0)
opensearch-dsl (~> 0.2.0)
opensearch-ruby (~> 1.0)
pg (~> 1.4)
Expand All @@ -672,6 +677,7 @@ DEPENDENCIES
roadie-rails (~> 3.0)
rotp (~> 6.2)
rqrcode (~> 2.1)
rswag-ui (~> 2.9)
rubocop (~> 1.48)
rubocop-capybara (~> 2.17)
rubocop-minitest (~> 0.29)
Expand Down
36 changes: 36 additions & 0 deletions app/controllers/api/base_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
class Api::BaseController < ApplicationController
skip_before_action :verify_authenticity_token

around_action :rswag

private

def name_params
Expand Down Expand Up @@ -117,4 +119,38 @@ def render_api_key_forbidden
def render_soft_deleted_api_key
render plain: "An invalid API key cannot be used. Please delete it and create a new one.", status: :forbidden
end

def rswag
f = Rails.root.join("app", "controllers", "api", "v1", "api.yaml")
schema = OpenAPIParser.load(f, { strict_reference_validation: true, strict_response_validation: true })
path = request.path
path = path.delete_suffix(".#{request.format.to_sym}")
path = path.sub("/api/v1", "")

ro = schema.request_operation(request.method.downcase.to_sym, path)
raise "No operation found for #{request.method} #{path}" unless ro

ro.validate_request_body(request.content_mime_type.to_s, request.request_parameters)
ro.validate_path_params

yield.tap do
ro.validate_response_body(
OpenAPIParser::RequestOperation::ValidatableResponseBody.new(response.status, deserialized_response_body, response.headers)
)
end
end

def deserialized_response_body
case Mime::Type.lookup response.content_type.sub(/^([^,;]*).*/, '\1').strip.downcase
when Mime::Type.lookup_by_extension(:json)
JSON.parse(response.body)
when Mime::Type.lookup_by_extension(:yaml)
YAML.safe_load(response.body)
when Mime::Type.lookup("text/plain")
response.body
else
raise "Unknown content type #{response.content_type} (#{response.content_type.sub(/^([^,;]*).*/, '\1')}) in response body: " +
response.body
end
end
end

0 comments on commit a9ed0b5

Please sign in to comment.