Микросервисы сейчас очень популярны и используются в различных архитектурах и средах. Слова Ruby и микросервисы, принято связывать с великолепным минималистичным фреймворком Sinatra.
Есть много хороших Ruby микро-фреймворков, но Grape вместе с Swagger UI через гем swagger действительно крут как быстрое, чистое и законченное решение. С Grape + Swagger UI мы можем создавать Restful API сервис при этом имея автоматически сгенерированный GUI для тестов и отладки API.
Обзор
От переводчика: Оригинал статьи
Пример микросервиса с Grape и Swagger
В качестве примера в данной статье мы создадим микросервис который предоставляет Restful CRUD ресурс - заметки.
От переводчика: на этом этапе вы должны знать или хотя бы понимать что такое REST, CRUD и API
Модель Note будет содержать:
- author
- title
- content
- summary
- timestamps
API будет предоставлять классические CRUD действия:
- create
- read
- update
- delete
- list
Весь код доступен в публичном репозитории.
Базовая структура приложения
На данном этапе структура и содержание проекта должны соответствовать коммиту - 20040af
├── app
│ └── core.rb
├── config.ru
├── Gemfile
└── Procfile
Мы будем использовать bundle для управления гемами и foreman для запуска приложения через команду foreman start
. Файл config.ru
будет подтягивать rubygems, bundle, core.rb
и запускать приложение. core.rb
в основном будет тянуть файлы нашего приложения: апи, модели и т.д.
Добавляем Grape и первый экшн
На данном этапе структура и содержание проекта должны соответствовать коммиту - 158fc4b
Grape - это REST-like API микро-фреймворк на Ruby. Он спроектирован так, что его можно запустить на Rack или добавить в существующее приложение на Rails или Sinatra. Предоставляет простой DSL для легкой разработки.
В качестве первого шага мы должны добавить grape гем и подключить его в нашем config.ru
. Затем добавим каталог api
с файлом ресурса api/notes.rb
и экшеном /test
. Также ./app/api/notes
должно быть подключено в файле config.ru
.
В файле api/notes.rb
используется Grape DSL:
version 'v1', using: :header, vendor: 'tonymadbrain'
format :json
resource 'notes' do
get '/test' do
{ data: "TEST" }
end
end
Приведя все к нужному виду, можем проверить наш первый экшн, для этого запустим приложение командой:
foreman start
От переводчика: если у вас не установлен foreman необходимо выполнить команду
gem install foreman
и откроем в браузере ссылку http://localhost:5000/notes/test. Мы должны увидеть следующее содержимое:
{“data”:”TEST”}
Добавляем Swagger и запускаем его через Rack
На данном этапе структура и содержание проекта должны соответствовать коммиту - 8b9ec95
Swagger - это простое и мощное представление RESTful API, включение его как сервиса может дать вам бесплатную интерактивную документацию, клиентский SDK и понятность. В нашем приложении мы хотим добавить swagger-ui - чистый html5 интерфейс для нашего API.
Сначала добавим гем grape-swagger который включает swagger для наших ресурсов. Добавим swagger документацию в app/api/notes.rb
:
add_swagger_documentation \
:info => {
:title => "Notes API"
},
:hide_documentation_path => true,
:mount_path => "/swagger_doc",
:markdown => false,
:api_version => 'v1'
Затем, скачаем swagger-ui в новый каталог public
. Теперь нам нужно сервить /public/swagger-ui
, для этого добавим гем rack-fiber_pool и добавим конфигурацию в config.ru
:
use Rack::Static,
:urls => ["/images", "/lib", "/js", "/css"],
:root => "public/swagger_ui"
map '/swagger-ui' do
run lambda { |env|
[
200,
{
'Content-Type' => 'txt-html',
'Cache-Control' => 'public, max-age=86400'
},
File.open('public/swagger_ui/index.html', File::RDONLY)
]
}
end
В итоге проверяем API уже со Swagger по ссылке http://localhost:5000/swagger-ui
Добавляем ActiveRecord, создаем таблицу и модель
ActiveRecord и его rake задачи
На данном этапе структура и содержание проекта должны соответствовать коммиту - 412226f
Для добавления ActiveRecord в наше приложение мы можем использовать гем grape-activerecord. Итак, вначале добавим rake
, mysql2
и grape-activerecord
гемы в наш Gemfile
. После установки можем настроить подключение к базе данных. Простой способ добавить добрый старый config/database.yml
.
Затем мы должны включить менеджер подключений ActiveRecord добавлением строки в config.ru
:
use ActiveRecord::ConnectionAdapters::ConnectionManagement
Добавление следующего Rake файла даст нам возможность использовать задачи базы данных:
require "bundler/setup"
require "grape/activerecord/rake"
namespace :db do
# Some db tasks require your app code to be loaded, or at least your gems
task :environment do
require_relative "app/core"
end
end
Запустим bundle exec rake -T
и увидим все доступные задачи.
Таблица и создание моделей
На данном этапе структура и содержание проекта должны соответствовать коммиту - 8cc1a84
Давайте создадим базу данных:
bundle exec rake db:create
Теперь миграции:
bundle exec rake db:create_migration NAME=create_table_notes
class CreateTableNotes < ActiveRecord::Migration
def change
create_table :notes do |t|
t.string :author
t.string :title
t.text :content
t.text :summary
t.boolean :private, default: false
t.integer :valuation
t.timestamps null: false
end
add_index :notes, :author
end
end
Теперь мы можем добавить нашу простую ActiveRecord модель Note в файле app/models/note.rb
.
class Note < ActiveRecord::Base
validates :author, :title, :content, presence: true
end
Добавляем Restful CRUD экшены в наш ресурс
На данном этапе структура и содержание проекта должны соответствовать коммиту - c4d1cdf
И, наконец, пришло время чтобы кодить наши CRUD экшены, методы desc и params передают swagger UI описание экшена и опциональные параметры с их типами и описаниями.
Создаем экшены с документацией и логикой:
desc 'Create a note.'
params do
requires :author, type: String, desc: 'Author'
requires :title, type: String, desc: 'Title'
requires :content, type: String, desc: 'Body'
optional :summary, type: String, desc: 'Summary'
optional :private, type: Boolean, desc: 'Private'
optional :valuation, type: Integer, desc: 'Valuation'
end
post '/' do
Note.create params
end
Swagger UI теперь должен показывать все экшены,
Заключение
В действительности этот пример очень простой, но он показывает как легко можно создавать микросервисы с документированным API на Ruby с помощью Grape и Swager.
Дополнительный бонус от использования Swagger это поддержка многих языков и фреймворков, мы получаем унифицированную документацию и UI для сервисов написанных на Java, Ruby, Python и т.д.
#Ruby #REST #API #Tutorial #TechAndDevОт переводчика: В некоторых моментах я не согласен с автором, например в оригинале используется каталог app/apis, у меня же app/api; использование foreman и activerecord избыточно; отсутсвует TDD и др.