API — одна из самых горячих тем в веб-разработке. С увеличением числа SPA (одностраничных приложений) и увлечением микросервисами API станут еще более популярными. Как разработчики Ruby on Rails, в нашем распоряжении есть удивительная среда, способная создавать API. Хотя Rails является мощным, он также более сложный. Иногда нам нужна более простая, более гибкая структура, которая делает только одну вещь и делает это хорошо. Я думаю, что нашел такую основу. Позвольте мне представить вам структуру, специально разработанную для создания API: Napa .
Napa объединяет такие гемы, как Grape , Roar и ActiveRecord, что позволяет нам создавать мощные API с минимальными усилиями. В этом уроке мы узнаем, как создать API с аутентификацией токена, используя Napa и Devise .
Установка Напа
Напа доступен как драгоценный камень, для которого требуется Ruby 2.0. Сначала нам нужно будет установить его, используя RVM или rbenv. Переключитесь на Ruby 2.0 и установите Napa:
gem install napa --no-ri --no-rdoc
Создание проекта
Сначала создайте проект с помощью генератора Напа:
napa new contact-service -d=pg
По умолчанию Napa генерирует настроенный проект MySQL. -d=pg
Napa создаст каталог проектов с именем contact-service и сгенерирует все необходимые каталоги и файлы. Проект структурирован следующим образом:
contact-service
- app
- apis
- models
- representers
- config
- db
- lib
- log
- spec
- Gemfile
- Rakefile
Структура очень похожа на Rails-приложение, но немного проще. Большая часть кода приложения попадает в каталог приложения . Наши API будут в ( apis ) каталоге apis . Модели попадут в каталог моделей , как и Rails. Один из новых битов здесь — это каталог представительств , в котором будут храниться представители рева. Представители преобразуют модели в желаемый вывод JSON. Другие каталоги служат той же цели, что и в приложении Rails.
Перейдите в каталог проекта и установите все гемы:
cd contact-service
bundle install
После установки гемов мы добавим детали базы данных в .env . Сначала создайте базу данных:
rake db:create
Давайте перейдем к следующему шагу.
Создание API
Время для хороших вещей, создавая актуальный API. Для этого нам сначала потребуется модель. Создайте модель контакта с некоторыми основными атрибутами, такими как имя, адрес электронной почты и номер телефона:
napa generate model Contact name:string email:string phone:string
Перенос базы данных:
rake db:migrate
Хорошо, теперь давайте создадим конечную точку API:
napa generate api contact
Napa сгенерирует класс API — app / apis / contacts_api.rb и класс представителя — app / представительс / contact_representer.rb . Класс contacts_api.rb должен выглядеть следующим образом:
class ContactsApi
По умолчанию Napa предоставляет пустое объявление параметров, которые должны быть приняты API. Это предусмотрено для защиты API от атак. Мы обновим блоки params
post
put
...
desc 'Create an contact'
params do
optional :name, type: String, desc: 'The Name of the contact'
optional :phone, type: String, desc: 'The Phone of the contact'
optional :email, type: String, desc: 'The Email Address of the contact'
end
...
...
desc 'Update a contact'
params do
optional :name, type: String, desc: 'The Name of the contact'
optional :phone, type: String, desc: 'The Phone of the contact'
optional :email, type: String, desc: 'The Email Address of the contact'
end
...
Теперь мы обновим класс contact_representer.rb . Добавьте поля модели Contact в классе, который должен быть частью ответов JSON. Обновите класс contact_representer.rb следующим образом:
class ContactRepresenter
Последняя оставшаяся часть — добавить API в application_api.rb , который монтирует API:
class ApplicationApi '/contacts'
add_swagger_documentation
end
Увольнение некоторых запросов
Наш API почти готов. Давайте проверим это, используя curl
Сначала запустите сервер разработки:
napa server
Теперь откройте другой терминал, чтобы мы могли запускать запросы в API. Сначала создайте контакт:
curl -X POST -d name="Devdatta Kane" -d email="[email protected]" -d phone="25451512544" http://localhost:9393/contacts
Ответ Напы всегда заключен в элемент data
{
"data": {
"object_type": "contact",
"id": "1",
"name": "Devdatta Kane",
"email": "[email protected]",
"phone": "25451512544"
}
}
Теперь, когда мы создали контакт, давайте попробуем получить все контакты:
curl -X GET http://localhost:9393/contacts
Ответом будет массив элементов.
{
"data": [
{
"object_type": "contact",
"id": "1",
"name": "Devdatta Kane",
"email": "[email protected]",
"phone": "25451512544"
}
]
}
Мы можем получить один контакт, передав идентификатор контакта:
curl -X GET http://localhost:9393/contacts/1
Который отвечает:
{
"data": {
"object_type": "contact",
"id": "1",
"name": "Devdatta Kane",
"email": "[email protected]",
"phone": "25451512544"
}
}
Попробуйте обновить контактные данные:
curl -X PUT -d email="[email protected]" http://localhost:9393/contacts/1
Напа возвращает обновленный объект:
{
"data": {
"object_type": "contact",
"id": "1",
"name": "Devdatta Kane",
"email": "[email protected]",
"phone": "25451512544"
}
}
Защита API
У нас есть полностью рабочий API. Ура! Но это совершенно небезопасно. БУ! Мы разрешаем доступ API без какой-либо аутентификации. Одним из наиболее простых используемых методов аутентификации для защиты API-интерфейсов является Token Authentication. Мы внедрим простую аутентификацию токена в нашем API, используя Devise . Мы могли бы также реализовать аутентификацию самостоятельно, но использование проверенной в битве библиотеки, такой как Devise, имеет свои преимущества.
Сначала добавьте Devise в наш Gemfile:
gem 'devise'
И обновите комплект:
bundle install
Devise теперь установлен, но нуждается в файле конфигурации. В Rails мы можем сгенерировать файл с помощью генератора Devise, но в Napa это не сработает. Поэтому мы вручную создадим файл в каталоге config / initializers . Создайте файл с именем devise.rb в этом каталоге и добавьте следующее:
Devise.setup do |config|
config.secret_key = '6e059f15248c9c26e7208a4a1129029c13f4a0fcef629562c34a4b3f0b1bbcbb8ed1431728cdbc6fe6e6bc4ed0f90cc9fc701c962e63be107e0bfd021eb70f08'
config.mailer_sender = '[email protected]'
require 'devise/orm/active_record'
config.authentication_keys = [:email]
config.case_insensitive_keys = [:email ]
config.strip_whitespace_keys = [:email ]
config.skip_session_storage = [:http_auth]
config.stretches = Rails.env.test? ? 1 : 10
config.password_length = 8..128
end
Замените config.secret_key
Теперь мы создадим модель User, используя генератор моделей Napa.
napa generate model User
Напа создаст модельный класс и миграцию. Откройте класс миграции и добавьте следующее:
...
def change
create_table :users do |t|
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
t.string :authentication_token
t.timestamps
end
add_index :users, :email, unique: true
add_index :users, :authentication_token, :unique => true
end
...
Откройте app / models / user.rb и добавьте следующее:
class User
Теперь, когда у нас есть модель и миграция, перенесите базу данных:
rake db:migrate
Мы создадим пользователя, используя консоль Napa, которую вы можете запустить:
napa console
pry(main)> User.create!(email:'[email protected]', password:'abcdabcd', password_confirmation:'abcdabcd')
Вы должны получить следующий вывод:
=> #<user id: 1, email: "[email protected]", encrypted_password: "$2a$10$vdRAL.CusK3IEBTopa1cau5WTLihyNDdssuAtU3otieq...", authentication_token: "yFjgn5cwsFAfKhvU1R_t", created_at: "2015-08-08 11:41:05", updated_at: "2015-08-08 11:41:05">
</user>
Существует authentication_token
Выходите из консоли.
Мы должны добавить поддержку аутентификации в наш API. Обновите app / apis / application_api.rb следующим образом:
class ApplicationApi '/contacts'
add_swagger_documentation
end
Теперь снова запустите napa server
curl -X GET http://localhost:9393/contacts
Это должно привести к ошибке, так как мы не передали токен доступа с запросом:
{"error":{"code":"api_error","message":"401 Unauthorized"}}
Попробуйте тот же запрос, но с токеном доступа:
curl -X GET http://localhost:9393/contacts\?access_token\=yFjgn5cwsFAfKhvU1R_t
И вы получите успешный ответ:
{
"data": {
"object_type": "contact",
"id": "1",
"name": "Devdatta Kane",
"email": "[email protected]",
"phone": "25451512544"
}
}
Заворачивать
Сегодня мы узнали, как быстро создавать API с помощью Napa. Napa предлагает дополнительную функциональность через промежуточное ПО, такое как ведение журнала и очистка конфиденциальных данных, которые вы можете изучить в репозитории Napa GitHub . Наше решение для аутентификации также может быть улучшено с помощью чего-то вроде OAuth и Access Grants, но я оставляю это упражнение для вас.
Комментарии и отзывы приветствуются, как всегда.