Skip to content

Instantly share code, notes, and snippets.

@edvakf
Last active June 27, 2018 02:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save edvakf/37a3e8b4dbbf87c8a7ae6696eb3ae715 to your computer and use it in GitHub Desktop.
Save edvakf/37a3e8b4dbbf87c8a7ae6696eb3ae715 to your computer and use it in GitHub Desktop.
RailsでViron対応管理画面を作る
# app/controllers/admin/api/application_controller.rb
class Admin::Api::ApplicationController < ActionController::Base
before_action :restrict_remote_ip if Rails.env.production?
def restrict_remote_ip
render text: 'Service Unavailable', status: 503 unless Rails.configuration.x.admin_permit_ip.include?(request.remote_ip)
end
def process_limit_offset
@offset = params[:offset]&.to_i || 0
@limit = params[:limit]&.to_i || 10
# viron独自のヘッダー https://cam-inc.github.io/viron-doc/docs/dev_component_table.html
response.headers['x-pagination-current-page'] = @offset / @limit + 1
response.headers['x-pagination-limit'] = @limit
response.headers['x-pagination-total-pages'] = 10 # 10ページ目までしか辿らせない
end
end
# app/controllers/concerns/swagger/admin/endpoints.rb
module Swagger::Admin::Endpoints
extend ActiveSupport::Concern
# エンドポイント一覧
included do
swagger_path '/viron' do
operation :get do
key :summary, 'Vironのグローバルメニュー'
key :operationId, 'viron#show'
response 200 do
key :description, 'ok'
schema do
key :'$ref', :Viron
end
end
end
end
swagger_path '/viron_authtype' do
operation :get do
key :summary, 'Vironの認証方式'
key :operationId, 'auth_type#list'
response 200 do
key :description, 'ok'
schema do
key :'$ref', :VironAuthtype
end
end
end
end
swagger_path '/admin/api/items' do
operation :get do
key :summary, 'アイテム一覧'
key :operationId, 'items#index'
parameter do
key :name, :limit
key :in, :query
key :required, false
key :type, :integer
end
parameter do
key :name, :offset
key :in, :query
key :required, false
key :type, :integer
end
response 200 do
key :description, 'ok'
schema do
key :type, :array
items do
key :'$ref', :Item
end
end
end
end
operation :post do
key :summary, 'アイテムを作成'
key :operationId, 'items#create'
parameter do
key :name, :payload
key :in, :body
key :required, true
schema do
key :'$ref', :Item
end
end
response 200 do
key :description, 'ok'
schema do
key :'$ref', :Item
end
end
end
end
swagger_path '/admin/api/items/{id}' do
operation :put do
key :summary, 'アイテムを編集'
key :operationId, 'items#update'
parameter do
key :name, :id
key :in, :path
key :required, true
key :type, :integer
end
parameter do
key :name, :payload
key :in, :body
key :required, true
schema do
key :'$ref', :ItemMod
end
end
response 200 do
key :description, 'ok'
schema do
key :'$ref', :Item
end
end
end
operation :delete do
key :summary, 'アイテムを削除'
key :operationId, 'items#delete'
parameter do
key :name, :id
key :in, :path
key :required, true
key :type, :integer
end
response 204 do
key :description, 'no content'
end
end
end
end
end
# app/controllers/admin/api/items_controller.rb
class Admin::Api::ItemsController < Admin::Api::ApplicationController
before_action :process_limit_offset, only: [:index]
def index
@items = Items.order(id: :desc).limit(@limit).offset(@offset) # Vironの定義次第で絞り込みパラメータもつけられる
end
def create
@item = Item.create!(params.permit(:name))
render :show
end
def update
@item = Item.find(params[:id])
@item.update!(params.permit(:name))
render :show
end
def delete
Item.destroy(params[:id])
head :no_content
end
end
# app/controllers/concerns/swagger/admin/objects.rb
module Swagger::Admin::Objects
extend ActiveSupport::Concern
# :objectというのはviron独自のタイプ https://github.com/cam-inc/viron/blob/7a338748a6fe0e5d92e8dc4ae490edbb81b95f85/src/components/viron-parameters/items/index.js#L23
included do
# ここらへんは /viron と /viron_authtype で使われるもの
swagger_schema :Viron do
key :required, [:name, :color, :thumbnail, :tags, :pages]
key :additionalProperties, false
property :name do
key :type, :string
end
property :color do
key :type, :string
key :default, 'white'
key :enum, ['white', 'black', 'purple', 'green', 'yellow', 'red', 'gray']
end
property :thumbnail do
key :type, :string
end
property :tags do
key :type, :array
items do
key :type, :string
end
end
property :pages do
key :type, :array
items do
key :'$ref', :Page
end
end
property :theme do
key :type, :string
key :default, 'standard'
key :enum, ['standard', 'midnight', 'terminal']
end
end
swagger_schema :VironAuthtype do
key :type, :array
items do
key :'$ref', :AuthType
end
end
swagger_schema :AuthType do
key :required, [:type, :url, :method, :provider]
key :additionalProperties, false
property :type do
key :type, :string
end
property :url do
key :type, :string
end
property :method do
key :type, :string
end
property :provider do
key :type, :string
end
end
swagger_schema :Page do
key :required, [:id, :name, :section, :group, :components]
key :additionalProperties, false
property :id do
key :type, :string
end
property :name do
key :type, :string
end
property :section do
key :type, :string
key :default, 'manage'
key :enum, ['manage', 'dashboard']
end
property :group do
key :type, :string
end
property :components do
key :type, :array
items do
key :'$ref', :Component
end
end
end
swagger_schema :Component do
key :required, [:api, :name, :style, :primary, :pagination, :query, :table_labels]
key :additionalProperties, false
property :api do
key :'$ref', :Api
end
property :name do
key :type, :string
end
property :style do
key :type, :string
key :enum, ['table']
end
property :primary do
key :type, :string
end
property :pagination do
key :type, :boolean
end
property :query do
key :type, :array
items do
key :'$ref', :Query
end
end
property :table_labels do
key :type, :array
items do
key :type, :string
end
end
# optional
property :actions do
key :type, :array
items do
key :type, :string
end
end
end
swagger_schema :Api do
key :required, [:method, :path]
key :additionalProperties, false
property :method do
key :type, :string
key :enum, ['get', 'post', 'put', 'delete'] # 他何があったっけ?
end
property :path do
key :type, :string
end
end
swagger_schema :Query do
key :required, [:key, :type]
key :additionalProperties, false
property :key do
key :type, :string
end
property :type do
key :type, :string
end
end
# ここから下は /admin/api/ 以下で使われるもの
swagger_schema :Item do
key :type, :object
key :required, [:id, :name]
key :additionalProperties, false
property :id do
key :type, :integer
end
property :name do
key :type, :string
end
end
end
end
# config/environments/production.rb
config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'https://viron.example.com/' # Viron管理画面のオリジン
resource '/admin/api/*', headers: :any, methods: [:get, :post, :delete, :put, :options], expose: ['X-Pagination-Limit', 'X-Pagination-Total-Pages', 'X-Pagination-Current-Page']
resource '/viron', headers: :any, methods: [:get]
resource '/viron_authtype', headers: :any, methods: [:get]
end
end
# routes.rb
namespace :admin do
namespace :api, format: 'json' do
resources :swagger, only: [:index] # /admin/api/swagger.json
resources :items, only: [:index, :create, :update, :delete]
end
end
get '/viron_authtype', to: 'viron#viron_authtype' # 将来的には/viron/authtypeになるかも https://github.com/cam-inc/viron/pull/329
get '/viron', to: 'viron#viron'
# app/controllers/admin/api/swagger_controller.rb
class Admin::Api::SwaggerController < Admin::Api::ApplicationController
include Swagger::Blocks
swagger_root do
key :swagger, '2.0'
info do
key :version, '0.0.0'
key :title, 'Gaia'
end
key :consumes, ['application/json']
key :produces, ['application/json']
if Rails.env.development?
key :schemes, ['http']
key :host, ['localhost:3000']
end
if Rails.env.production?
key :schemes, ['https']
key :host, ['example.com'] # 本番のホスト名に変えてね
end
end
# app/controllers/concerns/swagger/admin 以下を参照
include Swagger::Admin::Endpoints
include Swagger::Admin::Objects
# A list of all classes that have swagger_* declarations.
SWAGGERED_CLASSES = [
self,
].freeze
def index
render json: Swagger::Blocks.build_root_json(SWAGGERED_CLASSES)
end
end
# app/controllers/viron_controller.rb
class VironController < ApplicationController
# GET /viron_authtype
# https://cam-inc.github.io/viron-doc/docs/dev_api_authtype.html
def viron_authtype
render json: [].to_json
end
# GET /viron
# https://cam-inc.github.io/viron-doc/docs/dev_api_menu.html
def viron
render json: {
theme: 'standard',
color: 'white',
name: 'Viron example - local',
tags: [],
thumbnail: '', # サムネイル画像のURLを入れる
pages: [
{
section: 'manage',
group: 'item',
id: 'item',
name: 'アイテム',
components: [
{
api: {
method: 'get',
path: '/admin/api/items',
},
name: 'アイテム',
style: 'table',
primary: 'id',
pagination: true,
query: [], # ここを頑張れば絞り込みパラメータもつけられる
table_labels: [
'id',
'name',
],
actions: [],
},
],
},
],
}.to_json
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment