Skip to content

Instantly share code, notes, and snippets.

@andrius
Created December 18, 2023 09:48
Show Gist options
  • Save andrius/50e2965a9b0936a7c76f9d7f77bdc2a7 to your computer and use it in GitHub Desktop.
Save andrius/50e2965a9b0936a7c76f9d7f77bdc2a7 to your computer and use it in GitHub Desktop.
api with inputs.rewind issue
# api.rb
require 'bundler/setup'
require 'json'
require 'mongoid'
require 'grape'
require 'grape-swagger'
require 'grape-entity'
###############################################################################
# Config
#
Mongoid.configure do |config|
config.clients.default = {
uri: ENV.fetch('MONGODB_URI', 'mongodb://mongodb:27017/db')
}
end
###############################################################################
# Models
#
# Dir["./models/*.rb"].each { |file| require file }
# models/user.rb
class User
include Mongoid::Document
include Mongoid::Timestamps
ROLES = %w[system admin user].freeze
field :name, type: String
field :lastname, type: String
field :email, type: String
field :telephone, type: String
field :role, type: String, default: 'user'
validates :email, presence: true, uniqueness: true
validates :role, inclusion: { in: ROLES }
def entity
UserEntity.represent(self)
end
end
###############################################################################
# Entities
#
# Dir["./entities/*.rb"].each { |file| require file }
# entities/user_entity.rb
class UserEntity < Grape::Entity
expose :name, documentation: { type: "string", desc: "User name" }
expose :lastname, documentation: { type: "string", desc: "User lastname" }
expose :email, documentation: { type: "string", desc: "User email" }
expose :telephone, documentation: { type: "string", desc: "User telephone" }
expose :role, documentation: { type: "string", desc: "User role (admin, user etc)" }
end
###############################################################################
# API's
#
# Dir["./api/v1/*.rb"].each { |file| require file }
# api/v1/user.rb
module API
module V1
class Users < Grape::API
prefix :v1
resource :users do
desc "Return list of users"
get do
users = User.all
present users, with: UserEntity
end
desc "Return a user"
params do
requires :id, type: String, desc: "User ID"
end
route_param :id do
get do
user = User.find(params[:id])
present user, with: UserEntity
end
end
desc "Create a user"
params do
requires :name, type: String, desc: "User name"
requires :lastname, type: String, desc: "User lastname"
requires :email, type: String, desc: "User email"
requires :telephone, type: String, desc: "User telephone"
requires :role, type: String, desc: "User role"
end
post do
user = User.create!(name: params[:name], lastname: params[:lastname], email: params[:email],
telephone: params[:telephone], role: params[:role])
present user, with: UserEntity
end
desc "Update a user"
params do
requires :id, type: String, desc: "User ID"
optional :name, type: String, desc: "User name"
optional :lastname, type: String, desc: "User lastname"
optional :email, type: String, desc: "User email"
optional :telephone, type: String, desc: "User telephone"
optional :role, type: String, desc: "User role"
end
put ':id' do
user = User.find(params[:id])
user.update(name: params[:name], lastname: params[:lastname], email: params[:email],
telephone: params[:telephone], role: params[:role])
present user, with: UserEntity
end
desc "Delete a user"
params do
requires :id, type: String, desc: "User ID"
end
delete ':id' do
user = User.find(params[:id])
if user.role != 'system'
user.destroy
{ message: 'User deleted' }
else
error!('Cannot delete system user', 403)
end
end
end
end
end
end
###############################################################################
# API
#
module API
class Root < Grape::API
format :json
mount API::V1::Users
add_swagger_documentation(
info: {
title: "API",
description: "foobar",
contact_email: "foo@bar.com"
},
doc_version: 'v1',
hide_documentation_path: true
)
end
end
require_relative 'api'
run API::Root
version: '3'
volumes:
caddy_data:
caddy_config:
services:
mongodb:
image: mongo:latest
restart: unless-stopped
api:
depends_on:
- mongodb
build:
context: .
dockerfile: Dockerfile-dev
restart: unless-stopped
ports:
- "3000:3000"
environment:
# MONGODB_URI: 'mongodb://127.0.0.1:27017/db'
MONGODB_URI: 'mongodb://mongodb:27017/db'
RACK_ENV: development
volumes:
- ./:/app
FROM ruby
WORKDIR /app
COPY Gemfile* ./
RUN bundle install
CMD ["rackup", "-o", "0.0.0.0", "-p", "3000", "config.ru"]
source 'https://rubygems.org'
# Export .env file to ruby ENV
gem 'dotenv'
# MongoDB client
gem 'mongoid'
gem 'grape'
gem 'grape-entity'
gem 'grape-swagger'
# web
# gem 'puma'
gem 'rackup'
# group :development, :test do
# gem 'rspec'
# gem 'database_cleaner'
# end
GEM
remote: https://rubygems.org/
specs:
activemodel (7.1.2)
activesupport (= 7.1.2)
activesupport (7.1.2)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
minitest (>= 5.1)
mutex_m
tzinfo (~> 2.0)
base64 (0.2.0)
bigdecimal (3.1.5)
bson (4.15.0)
builder (3.2.4)
concurrent-ruby (1.2.2)
connection_pool (2.4.1)
dotenv (2.8.1)
drb (2.2.0)
ruby2_keywords
dry-core (1.0.1)
concurrent-ruby (~> 1.0)
zeitwerk (~> 2.6)
dry-inflector (1.0.0)
dry-logic (1.5.0)
concurrent-ruby (~> 1.0)
dry-core (~> 1.0, < 2)
zeitwerk (~> 2.6)
dry-types (1.7.1)
concurrent-ruby (~> 1.0)
dry-core (~> 1.0)
dry-inflector (~> 1.0)
dry-logic (~> 1.4)
zeitwerk (~> 2.6)
grape (2.0.0)
activesupport (>= 5)
builder
dry-types (>= 1.1)
mustermann-grape (~> 1.0.0)
rack (>= 1.3.0)
rack-accept
grape-entity (1.0.0)
activesupport (>= 3.0.0)
multi_json (>= 1.3.2)
grape-swagger (0.33.0)
grape (>= 0.16.2)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
minitest (5.20.0)
mongo (2.19.3)
bson (>= 4.14.1, < 5.0.0)
mongoid (8.1.4)
activemodel (>= 5.1, < 7.2, != 7.0.0)
concurrent-ruby (>= 1.0.5, < 2.0)
mongo (>= 2.18.0, < 3.0.0)
ruby2_keywords (~> 0.0.5)
multi_json (1.15.0)
mustermann (3.0.0)
ruby2_keywords (~> 0.0.1)
mustermann-grape (1.0.2)
mustermann (>= 1.0.0)
mutex_m (0.2.0)
rack (3.0.8)
rack-accept (0.4.5)
rack (>= 0.4)
rackup (2.1.0)
rack (>= 3)
webrick (~> 1.8)
ruby2_keywords (0.0.5)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
webrick (1.8.1)
zeitwerk (2.6.12)
PLATFORMS
aarch64-linux
DEPENDENCIES
dotenv
grape
grape-entity
grape-swagger
mongoid
rackup
BUNDLED WITH
2.4.22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment