# frozen_string_literal: true require 'roda/endpoints/endpoint/data' require 'roda/endpoints/endpoint/caching' require 'roda/endpoints/endpoint' require 'inflecto' require 'rom/sql' class Roda module Endpoints class Endpoint # HTTP endpoint representing a collection of items of the same type. class Collection < Roda::Endpoints::Endpoint prepend Data prepend Caching self.attributes += %i(item) self.defaults = defaults.merge( last_modified: :last_modified ) # @return [{Symbol=>Object}] attr_reader :item # @return [Time] def last_modified @last_modified ? repository.public_send(@last_modified) : super end # @param [Symbol] name # @param [Hash] params def child(name: item_name, type: Item, **params) super(name: name, type: type, **params) end # @return [Symbol] def item_name @item_name ||= Inflecto.singularize(name).to_sym end # @route /{collection.name} route do |r, endpoint| # r.collection :articles do |articles| r.last_modified endpoint.last_modified if endpoint.last_modified endpoint.verbs.each do |verb| # @route #{verb} /{collection.name} r.public_send(verb, transaction: verb) end # @route #{verb} /{collection.name}/{id} r.child **endpoint.item if endpoint.item # child by: :id end verb :get do |params| Right(repository.list(**params)) end verb :post do |params| params = params[item_name] || {} Right(repository.create(**params)) end # @route GET /{collection.name} transaction :get do |endpoint| step :retrieve, with: endpoint.operation_for(:get) end # @route POST /{collection.name} transaction :post do |endpoint| step :validate, with: endpoint.validation_for(:post) step :persist, with: endpoint.operation_for(:post) end end end end end