# frozen_string_literal: true require "sinatra" require 'docdsl' require "puma" require 'route_downcaser' class RestServer < Sinatra::Base set :server, :puma enable :logging if ENV["debug"] == "true" set :bind, "0.0.0.0" use RouteDowncaser::DowncaseRouteMiddleware register Sinatra::DocDsl page do title "Schmaless REST API" header "REST API using models #{Entities.models.keys}" introduction "REST APIs allowing CRUD on: #{Entities.models.keys.join("\n")}" end doc_endpoint "/docs" def has_id?(model, id) Entities.models[model].key?(id) end def not_have(id) [404, JSON.generate({ error: "'#{id}' not found" })] end documentation "Get summary" do response "Basic basic summary of API" end get "/" do summary = { models: Entities.models.keys.to_s, docs_url: '/docs' } summary[:db] = MongoClient.client.summary.to_s if ENV['mongodb'] JSON.generate(summary) rescue Exception => e [500, e.message] end Entities.models.each_key do |model| documentation "Create instance of #{model}" do payload "Whatever JSON you want. Needs to be valid JSON" response "Id of created #{model}" status 201 end post "/#{model.downcase}" do data = JSON.parse(request.body.read) id = '' if (data['id']) id = data['id'].to_s else id = SecureRandom.uuid data['id'] = id end if ENV['mongodb'] MongoClient.insert(model, data, id) else Entities.models[model][id] = data end [201, JSON.generate({ id: id })] end documentation "Retrieve all instances of #{model} or filtered by query param" do response "Data in #{model}" query_param :key_to_search_in_data, "Value of key" status 200 end get "/#{model.downcase}" do puts request.path.downcase if ENV['mongodb'] if params == {} JSON.generate(MongoClient.get_all(model)) else [200, JSON.generate(MongoClient.find_all(model, params))] end else return JSON.generate(Entities.models[model].values) if params == {} Entities.models[model].values.find_all { |val| val[params.keys[0]] == params.values[0] } end rescue Exception => e [404, "Nothing found using #{params}. Only first param considered. #{e.message}"] end documentation "Retrieve specific instance of #{model} by id" do response "Data in #{model}" status 200 status 404 end get "/#{model.downcase}/:id" do |id| puts request.path.downcase if ENV['mongodb'] results = MongoClient.find(model, id) return not_have(id) unless results.first JSON.generate(results.first) else return not_have(id) unless has_id?(model, id) JSON.generate(Entities.models[model][id]) end end documentation "Update id of #{model} to be provided data" do payload "Whatever JSON you want updated to be. Needs to be valid JSON" response "Data in #{model}" status 204 status 404 end put "/#{model.downcase}/:id" do |id| puts request.path.downcase data = JSON.parse(request.body.read) if ENV['mongodb'] results = MongoClient.find(model, id) return not_have(id) unless results.first MongoClient.update(model, id, data) else return not_have(id) unless has_id?(model, id) Entities.models[model][id] = data end 204 end documentation "Update id of #{model} to be deleted" do response "Empty" status 204 end delete "/#{model.downcase}/:id" do |id| puts request.path.downcase if ENV['mongodb'] results = MongoClient.find(model, id) return not_have(id) unless results.first MongoClient.delete(model, id) else return not_have(id) unless has_id?(model, id) Entities.models[model].delete(id) end 204 end end end