lib/hyperdrive/resource.rb in hyperdrive-0.0.5 vs lib/hyperdrive/resource.rb in hyperdrive-0.0.6

- old
+ new

@@ -1,72 +1,116 @@ # encoding: utf-8 module Hyperdrive class Resource - attr_reader :endpoint, :allowed_params, :filters, :request_handlers - attr_accessor :name, :desc + include Hyperdrive::Values + attr_reader :id, :namespace, :endpoint, :params, :filters, :request_handlers, :version + attr_accessor :name, :description - def initialize(key) - @key = key - @endpoint = "/#{@key.to_s.en.plural}" - @allowed_params = default_allowed_params + def initialize(name, hyperdrive_config = hyperdrive.config) + @namespace = name.to_s.en.plural + @endpoint = "/#{namespace}" + @params = default_params @filters = default_filters @request_handlers = default_request_handlers + @config = hyperdrive_config + @id = [@config[:vendor], @namespace].join(':') end - def register_param(key, description, options = {}) - options = default_param_options.merge(options) - @allowed_params[key] = { desc: description }.merge(options) + def register_param(param, description, options = {}) + @params[param] = Param.new(param, description, options) end - def register_filter(key, description, options = {}) - options = default_filter_options.merge(options) - @filters[key] = { desc: description }.merge(options) + def register_filter(filter, description, options = {}) + @filters[filter] = Filter.new(filter, description, options) end - def define_request_handler(request_method, block) - @request_handlers[request_method] = block + def register_request_handler(request_method, request_handler, version = 'v1') + @request_handlers[request_method] ||= {} + @request_handlers[request_method].merge!({ version => request_handler }) if request_method == :get - @request_handlers[:head] = block + @request_handlers[:head] ||= {} + @request_handlers[:head].merge!({ version => @request_handlers[:get][version] }) end end - def request_handler(http_request_method) - request_method = Hyperdrive::Values.request_methods_string_map[http_request_method] - request_handlers[request_method] + def request_handler(http_request_method, version = nil) + version ||= latest_version(http_request_method) + request_method = http_request_methods[http_request_method] + request_handlers[request_method][version] end + def acceptable_content_types(http_request_method) + content_types = [] + @config[:media_types].each do |media_type| + available_versions(http_request_method).each do |version| + content_types << "application/vnd.#{@config[:vendor]}.#{namespace}.#{version}+#{media_type}" + end + content_types << "application/vnd.#{@config[:vendor]}.#{namespace}+#{media_type}" + content_types << "application/vnd.#{@config[:vendor]}+#{media_type}" + end + content_types + end + + def available_versions(http_request_method) + request_method = http_request_methods[http_request_method] + @request_handlers[request_method].keys.sort.reverse + end + + def latest_version(http_request_method) + available_versions(http_request_method).first + end + def request_method_allowed?(http_request_method) allowed_methods.include?(http_request_method) end def allowed_methods - Hyperdrive::Values.request_methods_symbol_map.values_at(*request_handlers.keys) + request_methods.values_at(*request_handlers.keys) end - private + def required_param?(param, http_request_method) + return false if %w(GET HEAD OPTIONS).include? http_request_method + params.key?(param) and params[param].required?(http_request_method) + end - def default_allowed_params + def required_filter?(filter, http_request_method) + return false unless %w(GET HEAD OPTIONS).include? http_request_method + filters.key?(filter) and filters[filter].required?(http_request_method) + end + + def required?(param, http_request_method) + required_param?(param, http_request_method) or required_filter?(param, http_request_method) + end + + def to_hash { - id: { desc: 'Resource Identifier', required: %w(PUT PATCH DELETE) } + _links: { 'self' => { href: endpoint } }, + id: id, + name: name, + description: description, + methods: allowed_methods, + params: params.map { |_,param| param.to_hash }, + filters: filters.map { |_,filter| filter.to_hash }, + media_types: allowed_methods.map { |method| acceptable_content_types(method) }.uniq } end - def default_param_options - { required: true }.freeze + private + + def default_params + { + id: Param.new(:id, 'Identifier', required: %w(PUT PATCH DELETE)) + } end def default_filters { - id: { desc: 'Resource Identifier', required: false } + id: Filter.new(:id, 'Resource Identifier', required: false) } end - def default_filter_options - { required: false }.freeze - end - def default_request_handlers - { options: proc { '' } } + { options: { 'v1' => proc { |env| '' } } } end end end