Внизу от SitePoint, команда 99designs недавно модернизировала свое сокращение URL, чтобы поддерживать множество новых функций. Используя комбинацию Синатры и Героку , я был ошеломлен тем, как легко это было.
Что мы строим
Прежде чем я начну, позвольте мне прояснить: мы не создаем полноценное сокращение URL, как bit.ly или TinyURL . Вместо этого мы собираемся принять запрос типа http://gentle-light-20.heroku.com/khw
В этом примере мы отправим пользователя по http://www.sitepoint.com/?p=26564
Я также предположил, что в вашей системе установлено следующее:
- Рубин
- система управления пакетами Gem
- рамки тестирования RSpec
- Гит
Если вам нужна помощь в этом, в Руководстве по быстрому старту Heroku есть ссылки, которые могут вам помочь.
Записка по номерам базы 36
В приведенном выше примере вам может быть интересно, как мы переходим с khw
26564
Ну, khw
Если вы знакомы с шестнадцатеричными цветовыми кодами, вы будете знакомы с идеей системы подсчета основ 16. Именно здесь цифры могут быть не только между 0 и 9, но также могут быть A (что соответствует 10), B (что соответствует 11) и т. Д. До F (который имеет значение 15).
Система нумерации Base 36 расширяет эту идею, так что цифра может быть в диапазоне от 0 до 9 или от A до Z. В таблице ниже приведены некоторые примеры чисел Base 36 и их десятичных аналогов:
База 36 номер | Десятичное значение |
---|---|
9 | 9 |
10 | |
В | 11 |
Y | 34 |
Z | 35 |
10 | 36 |
1BC | 47064 |
Шаг 1: Настройте свою среду
Для начала нам нужно установить несколько Gems. Gems — это библиотеки Ruby, которые можно установить с помощью команды gem
Для нашего приложения нам понадобится установить следующие гемы:
-
heroku
-
rspec
-
sinatra
-
rack
rack-test,
Чтобы установить эти драгоценные камни, выполните следующие команды:
$ sudo gem install heroku
Successfully installed rake-0.8.7
Successfully installed mime-types-1.16
⋮
Installing RDoc documentation for json_pure-1.4.6...
Installing RDoc documentation for heroku-1.10.5...
$ sudo gem install sinatra
Successfully installed rack-1.2.1
Successfully installed sinatra-1.0
⋮
Installing RDoc documentation for rack-1.2.1...
Installing RDoc documentation for sinatra-1.0...
$ sudo gem install rspec
**************************************************
Thank you for installing rspec-1.3.0
Please be sure to read History.rdoc and Upgrade.rdoc
for useful information about this release.
**************************************************
Successfully installed rspec-1.3.0
⋮
Could not find main page README.rdoc
$ sudo gem install rack
Successfully installed rack-1.2.1
1 gem installed
Installing ri documentation for rack-1.2.1...
Installing RDoc documentation for rack-1.2.1...
$ sudo gem install rack-test
Successfully installed rack-test-0.5.4
1 gem installed
Installing ri documentation for rack-test-0.5.4...
Installing RDoc documentation for rack-test-0.5.4...
$
Шаг 2: написать несколько тестов
Теперь, когда у нас установлены Gems, мы можем начать писать код на Ruby. Давайте начнем с нескольких простых тестов. Создайте каталог с именем my-url-shortener
Затем внутри файла my-url-shortener-test.rb
require "my-url-shortener"
require "spec"
require "rack/test"
set :environment, :test
describe "My URL Shortener" do
include Rack::Test::Methods
def app
Sinatra::Application
end
it "redirects to a blog post" do
get "/123" # 123 (base 36) == 1371 (base 10)
last_response.status.should == 301
last_response.headers["location"].should == "http://www.sitepoint.com/?p=1371"
end
it "redirect to blog post with lowercase digits" do
get "/a" # a (base 36) == 10 (base 10)
last_response.status.should == 301
last_response.headers["location"].should == "http://www.sitepoint.com/?p=10"
end
it "redirect to blog post with uppercase digits" do
get "/A" # A (base 36) == 10 (base 10)
last_response.status.should == 301
last_response.headers["location"].should == "http://www.sitepoint.com/?p=10"
end
it "redirects to home" do
get "/"
last_response.status.should == 301
last_response.headers["location"].should == "http://www.sitepoint.com/"
end
it "unrecognised path redirects" do
get "/foo/bar"
last_response.status.should == 301
last_response.headers["location"].should == "http://www.sitepoint.com/foo/bar"
end
end
В приведенном выше коде мы тестируем следующие перенаправления:
Запрашиваемый путь | Перенаправить пункт назначения |
---|---|
/123 |
http://www.sitepoint.com/?p=1371 |
/A |
http://www.sitepoint.com/?p=10 |
/a |
http://www.sitepoint.com/?p=10 |
/ |
http://www.sitepoint.com/ |
/foo/bar |
http://www.sitepoint.com/foo/bar |
Выполнение этих тестов будет работать только в том случае, если есть класс my-url-shortener
Синатра сделает всю работу за нас, если мы просто создадим файл my-url-shortener.rb
require "sinatra"
Теперь мы можем запустить тест, введя spec my-url-shortener-test.rb
$ spec my-url-shortener-test.rb
FFFFF
1)
'My URL Shortener redirects to a blog post' FAILED
expected: 301,
got: 404 (using ==)
./my-url-shortener-test.rb:16:
2)
'My URL Shortener redirect to blog post with lowercase digits' FAILED
expected: 301,
got: 404 (using ==)
./my-url-shortener-test.rb:22:
3)
'My URL Shortener redirect to blog post with uppercase digits' FAILED
expected: 301,
got: 404 (using ==)
./my-url-shortener-test.rb:28:
4)
'My URL Shortener redirects to home' FAILED
expected: 301,
got: 404 (using ==)
./my-url-shortener-test.rb:34:
5)
'My URL Shortener unrecognised path redirects' FAILED
expected: 301,
got: 404 (using ==)
./my-url-shortener-test.rb:40:
Finished in 0.020694 seconds
5 examples, 5 failures
Здесь мы видим, что все пять тестов не пройдены, и наш перенаправитель просто возвращает 404. Давайте сделаем что-нибудь с этим, не так ли?
Шаг 3: написать заявку
Добавьте следующее в my-url-shortener.rb
get %r{^/([0-9a-zA-Z]+)$} do
postid = params[:captures][0].to_i(36)
redirect "http://www.sitepoint.com/?p=#{postid}", 301
end
Эти четыре строки:
- перехватывать любой запрос, соответствующий регулярному выражению
^/([0-9a-zA-Z]+)$
- извлечь идентификатор сообщения из входящего запроса, преобразовав число 36 в целое число,
- перенаправить пользователя на
http://www.sitepoint.com/?p=postid
- прекратить обработку этого запроса
Повторный запуск теста показывает, что мы добились определенного прогресса:
$ spec my-url-shortener-test.rb
...FF
1)
'My URL Shortener redirects to home' FAILED
expected: 301,
got: 404 (using ==)
./my-url-shortener-test.rb:34:
2)
'My URL Shortener unrecognised path redirects' FAILED
expected: 301,
got: 404 (using ==)
./my-url-shortener-test.rb:40:
Finished in 0.0337120000000001 seconds
5 examples, 3 failures
Три точки в первой строке этих результатов показывают, что три наших теста пройдены. Два оставшихся случая можно обработать, добавив ловушку в конец my-url-shortener.rb
get "/*" do
path = params["splat"]
redirect "http://www.sitepoint.com/#{path}", 301
end
Давайте попробуем запустить тесты сейчас:
$ spec my-url-shortener-test.rb
.....
Finished in 0.008923 seconds
5 examples, 0 failures
Успех!
Теперь давайте развернем эту присоску в Heroku.
Шаг 4: развернуть в Heroku
Для развертывания в Heroku нам потребуется настроить два файла конфигурации: один с именем .gems,
config.ru
Эти файлы, как и другие в этом проекте, очень просты.
Поместите это в .gems
sinatra
Поместите это в config.ru
require "my-url-shortener"
run Sinatra::Application
Теперь мы готовы развернуть наше приложение. Если вы еще этого не сделали, посетите Heroku и зарегистрируйтесь. Как только вы это сделаете, выполните инструкции из Руководства по быстрому запуску Heroku, чтобы создать базовое приложение Heroku.
В Mac OS X это сводится к:
$ cd ~/my-url-shortener/
$ git init
Initialized empty Git repository in /Users/craiga/my-url-shortener/.git/
$ git add .
$ git commit -m "Creating URL shortener application"
[master (root-commit) b602ee0] Creating URL shortener application
4 files changed, 57 insertions(+), 0 deletions(-)
create mode 100644 .gems
create mode 100644 config.ru
create mode 100644 my-url-shortener-test.rb
create mode 100644 my-url-shortener.rb
$ heroku create
Enter your Heroku credentials.
Email: [email protected]
Password:
Uploading ssh public key /Users/craiga/.ssh/id_rsa.pub
Creating gentle-light-20... done
Created http://gentle-light-20.heroku.com/ | [email protected]:gentle-light-20.git
Git remote heroku added
$ git push heroku master
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 940 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)
-----> Heroku receiving push
-----> Sinatra app detected
-----> Installing gem sinatra from http://rubygems.org
Successfully installed sinatra-1.0
1 gem installed
Compiled slug size is 236K
-----> Launching.... done
http://gentle-light-20.heroku.com deployed to Heroku
To [email protected]:gentle-light-20.git
* [new branch] master -> master
Boom! Ваше приложение было развернуто в Heroku. Проверьте это, посетив URL, который дал вам Heroku (в приведенном выше примере это http://gentle-light-20.heroku.com
Шаг 5: Нет пятого шага!
И это все. Если у вас есть короткий домен, который вы хотели бы использовать, например, домен 99d.me, который мы используем здесь на 99designs, вы можете назначить его своему веб-сайту с помощью инструментов на сайте Heroku. На момент написания статьи вам нужно будет ввести номер вашей кредитной карты, но с вас будет взиматься плата только в том случае, если вам нужно много места в базе данных или более высокая производительность.