[RUBY] I want to introduce the committee with Rails without getting too dirty

Overview

--I want to introduce Request and Response Validation in the committee to add API for public release to Rails project. --If you put it as middleware of Rack, it will affect the existing processing.

manner

Add committee to Gemfile and bundle install.

gem 'committee'

All you have to do now is create a class to use the committee and call it from the Controller.

lib/public_api/committee_validator.rb


module PublicApi
  class CommitteeValidator
    attr_reader :request_object

    def initialize(request_object)
      @request_object = request_object
    end

    def committee_options
      {
        schema_path: Rails.root.join('schema', 'swagger.yml').to_s,
        prefix: '/public_api/v1'
      }
    end

    def validate_request!
      unless schema_validator.link_exist?
        request = "`#{request_object.request_method} #{request_object.path_info}` undefined in schema."
        raise Committee::InvalidRequest.new(request)
      end

      schema_validator.request_validate(request_object)
    end

    def validate_response!(status, headers, body)
      schema_validator.response_validate(status, headers, [body], true) if validate_response?(status)
    end

    def validate_response?(status)
      Committee::Middleware::ResponseValidation.validate?(status, committee_options.fetch(:validate_success_only, false))
    end

    def schema
      @schema ||= Committee::Middleware::Base.get_schema(committee_options)
    end

    def router
      @router ||= schema.build_router(committee_options)
    end

    def schema_validator
      @schema_validator ||= router.build_schema_validator(request_object)
    end
  end
 end

app/controllers/public_api/v1/base_controller.rb


module PublicApi
  module V1
    class BaseController < ApplicationController
      before_action :validate_request
      after_action :validate_response

      private

      def committee_validator
        @committee_validator ||= ::PublicApi::CommitteeValidator.new(request)
      end

      def validate_request
        committee_validator.validate_request!
      rescue Committee::InvalidRequest => e
        # render_bad_request
      end

      def validate_response
        committee_validator.validate_response!(response.status, response.headers, response.body)
      rescue StandardError => e
        Rails.logger.error("#{e.class}: #{ex.message}\n#{ex.backtrace.join("\n")}")
      end
   end
end

After that, rescue it nicely and change the process according to the specifications. With this kind of feeling, you can introduce it while suppressing the influence on the outside of Public Api!

Recommended Posts

I want to introduce the committee with Rails without getting too dirty
I want to play with Firestore from Rails
[Rails] I want to load CSS with webpacker
I want to dark mode with the SWT app
I want to authenticate users to Rails with Devise + OmniAuth
I want to hit the API with Rails on multiple docker-composes set up locally
I tried to introduce Bootstrap 4 to the Rails 6 app [for beginners]
[Rails] [bootstrap] I want to change the font size responsively
I want to push an app made with Rails 6 to GitHub
[With back tricks] How to introduce React to the simplest Rails
I want to create a form to select the [Rails] category
I want to distinct the duplicated data with has_many through
I want to pass the startup command to postgres with docker-compose.
After posting an article with Rails Simple Calendar, I want to reflect it in the calendar.
I want to convert an array to Active Record Relation with Rails
I want to add a browsing function with ruby on rails
I want to return to the previous screen with kotlin and java!
I tried to implement the image preview function with Rails / jQuery
[Java] I want to perform distinct with the key in the object
[Rails] I want to add data to Params when transitioning with link_to
I want to use DBViewer with Eclipse 2018-12! !!
I want to test Action Cable with RSpec test
I rewrote the Rails tutorial test with RSpec
I want to output the day of the week
I want to control the start / stop of servers and databases with Alexa
[Rails] I tried to raise the Rails version from 5.0 to 5.2
I tried to organize the session in Rails
[Rails / ActiveRecord] I want to validate the value before the type is converted (_before_type_cast)
I want to be able to read a file using refile with administrate [rails6]
I want to var_dump the contents of the intent
The code I used to connect Rails 3 to PostgreSQL 10
[Rails] [Parent-child relationship] I want to register the foreign key in the child with nil when the parent is deleted.
[Eclipse] I want to use the completion function, but I want to manage to confirm the completion with spaces.
I want to truncate after the decimal point
I want to see the contents of Request without saying four or five
Try to summarize the common layout with rails
I want to perform aggregation processing with spring-batch
I want to get the value in Ruby
[Rails] I want to test with RSpec. We support your step [Introduction procedure]
Rails The concept of view componentization of Rails that I want to convey to those who want to quit
I want to see only the latest because the Docker log has become too large
I want to change the path after new registration after logging in with multiple devises.
[Rails] I want to display the link destination of link_to in a separate tab
[Java] I want to calculate the difference from the date
I want to embed any TraceId in the log
[Java 11] I tried to execute Java without compiling with javac
I want to use fish shell in Laradock too! !!
[Rails] I tried playing with the comment send button
I want to use ES2015 in Java too! → (´ ・ ω ・ `)
I want to use a little icon in Rails
I want to know the answer of the rock-paper-scissors app
I want to display the name of the poster of the comment
I want to monitor a specific file with WatchService
I want to define a function in Rails Console
Rails6 I tried to introduce Docker to an existing application
I want to transition screens with kotlin and java!
I want to call the main method using reflection
Addicted to the webpacker that comes standard with Rails 6
[Rough commentary] I want to marry the pluck method
I want to get along with Map [Java beginner]
I want to be aware of the contents of variables!