intridea/grape

View on GitHub
lib/grape/dsl/desc.rb

Summary

Maintainability
A
1 hr
Test Coverage
# frozen_string_literal: true

module Grape
  module DSL
    module Desc
      include Grape::DSL::Settings

      ROUTE_ATTRIBUTES = %i[
        body_name
        consumes
        default
        deprecated
        description
        detail
        entity
        headers
        hidden
        http_codes
        is_array
        named
        nickname
        params
        produces
        security
        summary
        tags
      ].freeze

      # Add a description to the next namespace or function.
      # @param description [String] descriptive string for this endpoint
      #   or namespace
      # @param options [Hash] other properties you can set to describe the
      #   endpoint or namespace. Optional.
      # @option options :detail [String] additional detail about this endpoint
      # @option options :summary [String] summary for this endpoint
      # @option options :params [Hash] param types and info. normally, you set
      #   these via the `params` dsl method.
      # @option options :entity [Grape::Entity] the entity returned upon a
      #   successful call to this action
      # @option options :http_codes [Array[Array]] possible HTTP codes this
      #   endpoint may return, with their meanings, in a 2d array
      # @option options :named [String] a specific name to help find this route
      # @option options :body_name [String] override the autogenerated body name param
      # @option options :headers [Hash] HTTP headers this method can accept
      # @option options :hidden [Boolean] hide the endpoint or not
      # @option options :deprecated [Boolean] deprecate the endpoint or not
      # @option options :is_array [Boolean] response entity is array or not
      # @option options :nickname [String] nickname of the endpoint
      # @option options :produces [Array[String]] a list of MIME types the endpoint produce
      # @option options :consumes [Array[String]] a list of MIME types the endpoint consume
      # @option options :security [Array[Hash]] a list of security schemes
      # @option options :tags [Array[String]] a list of tags
      # @yield a block yielding an instance context with methods mapping to
      #   each of the above, except that :entity is also aliased as #success
      #   and :http_codes is aliased as #failure.
      #
      # @example
      #
      #     desc 'create a user'
      #     post '/users' do
      #       # ...
      #     end
      #
      #     desc 'find a user' do
      #       detail 'locates the user from the given user ID'
      #       failure [ [404, 'Couldn\'t find the given user' ] ]
      #       success User::Entity
      #     end
      #     get '/user/:id' do
      #       # ...
      #     end
      #
      def desc(description, options = {}, &config_block)
        if config_block
          endpoint_configuration = if defined?(configuration)
                                     # When the instance is mounted - the configuration is executed on mount time
                                     if configuration.respond_to?(:evaluate)
                                       configuration.evaluate
                                     # Within `given` or `mounted blocks` the configuration is already evaluated
                                     elsif configuration.is_a?(Hash)
                                       configuration
                                     end
                                   end
          endpoint_configuration ||= {}
          config_class = desc_container(endpoint_configuration)

          config_class.configure do
            description description
          end

          config_class.configure(&config_block)
          Grape.deprecator.warn('Passing a options hash and a block to `desc` is deprecated. Move all hash options to block.') if options.any?
          options = config_class.settings
        else
          options = options.merge(description: description)
        end

        namespace_setting :description, options
        route_setting :description, options
      end

      # Returns an object which configures itself via an instance-context DSL.
      def desc_container(endpoint_configuration)
        Module.new do
          include Grape::Util::StrictHashConfiguration.module(*ROUTE_ATTRIBUTES)
          config_context.define_singleton_method(:configuration) do
            endpoint_configuration
          end

          def config_context.success(*args)
            entity(*args)
          end

          def config_context.failure(*args)
            http_codes(*args)
          end
        end
      end
    end
  end
end