Статьи

Сборка APIbunny — Использование Fortune.js и JSONAPI

[Эта статья была первоначально написана Николаем в 3Scale.]

Если вы являетесь частью мира API, вы, возможно, слышали о конкурсе APIbunny, который мы начали в прошлую пятницу. Вот история этого 3-дневного проекта.

Какой любимый спорт у людей на Пасху? Охота на яйца, конечно. В 3scale нам пришла в голову идея сделать что-то особенное к Пасхе, способ отпраздновать праздничное время охоты на яйцо вызывающим способом. Что-то, где хакерам на самом деле не придется выходить на улицу — но все же можно повеселиться с вызовом в духе сезона!

Идея состояла в том, чтобы создать лабиринт, в котором хакерам нужно найти выход, и в конце на выигрышной странице получить свой приз, и, наконец, написать в Твиттере о своих поисках. А.И.Банни родился.

APIbunny_quest

Мы решили сделать это на основе гипермедиа, чтобы попробовать что-то новое, и потому что людям также будет легче подобрать. Затем я потратил один день, чтобы прочитать как можно больше об API HyperMedia. Я посмотрел отличные доклады Стива Клабника , прочитал большинство презентаций Slideshare, которые я смог найти по этой теме, и нашел отличное учебное пособие от Джейсона Роудса, которое проведет вас через RPC, REST и Hypermedia.

Используемая технология

В ранние дни программирования я почти исключительно использовал PHP и Ruby, сейчас я нахожусь на этапе Javascript и не вижу себя использующим другие технологии. Я был рад узнать, что в конце своего урока Джейсон дает обзор Fortune.js , фреймворка, предназначенного для создания API-интерфейсов Hypermedia в Javascript. Именно то, что я искал! 🙂

Это кажется таким простым: вы определяете объекты и отношения между ними, а фреймворк создает ссылки. Мы использовали два ресурса, лабиринт и клетку. Лабиринт имеет несколько ячеек, и клетка принадлежит лабиринту, она также связана с другими клетками.

Как это выглядит на Fortune.js

var mazeAPI = fortune({
 db: "./db/maze-data"
});

mazeAPI.resource('maze',{
    name: String,
    cells: ['cell'],
    start: {ref: 'cell',inverse:'null'}
});

mazeAPI.resource('cell',{
    name: String,
    readableId: Number,
    north: {ref:'cell', inverse:’south’},
    east: {ref:'cell', inverse:’west’},
    south: {ref:'cell', inverse:'north’},
    west: {ref:'cell', inverse:'east'},
    maze: {ref: 'maze'},
});

Мы только те несколько строк кода, которые мы определили наш API и наши конечные точки. Определенные таким образом коллекции идут с уже встроенными HTTP-действиями. Таким образом , у вас есть доступ к GET, POST, DELETE, PUT, PATCHна /mazesи /cells.

В Fortune.js вы также можете обратные отношения. Если ячейка A имеет восточные отношения с ячейкой B, это также означает, что B имеет западные отношения с B. Это может быть очень полезно, но это не очень хорошо работает в случае лабиринта.

| 1 | 4 | 7 |
| 2 | 5 | 8 |
| 3 | 6 | 9 |

Ячейка № 4 должна иметь

{
 west:1
 east:7
 south:5
}

Но из-за того, что инверсия # 4 также находится на востоке от # 7, так что # 4 на западе становится 7.
Таким образом, мы должны использовать nullвместо этого инверсию .

Создание лабиринта

Для описания лабиринта я использовал тот же формат ввода, что и Майк Амундсен в своей книге. Файл JavaScript с массивом ячеек с их свойствами.
Скрипт, который генерирует лабиринт, добавит ячейки в лабиринт, вызвав API. Когда все ячейки будут созданы, он снова будет проходить через файл и строить отношения между ячейками, используя PATCHзапросы. Это также, как мы определили начальную точку лабиринта.

Выход из лабиринта

Поскольку мы хотели, чтобы API был машиночитаемым, мы добавили typeатрибуты в ячейки для распознавания точек начала и выхода из других ячеек. Достижение выходной ячейки лабиринта было только частью решения квеста. Мы хотели отправить хакеров на страницу победителей, где они могли бы поделиться своей гордостью за победу в квесте. В идеале эта выигрышная страница должна быть уникальной, требующей от хакеров разгадать лабиринт, а не просто найти URL-адрес победившей страницы.

APIbunny_last_cell_curl

Вот где многие люди застряли. В exit_link атрибуты не гипермедиа уступчивые, и должны были быть в массиве ссылок. Для этого мы должны были объявить его как ссылку в Fortune.js на объект ячейки, и тогда exit_link был бы доступен в каждой ячейке. И было бы легче найти URL, чтобы разблокировать выигрышную страницу.

Когда хакеры получили эту ссылку, большинство из них застряли и не нашли, как ее использовать. Они поняли, что должны сделать POSTзапрос к нему, но формат запроса не был обычным запросом REST POST, потому что Fortune.js генерирует JSON-API тип гипермедиа API.

В APIbunny вызов выглядит так

{"users":[{"twitter_handle":"mytwitterhandle"}]}

Мы намекали об этом на целевой странице, сообщая, что мы используем JSON-API . Некоторые из вас нашли это в официальной документации .

«Защитить» API

Когда вы запускаете такой вызов и просите хакеров взломать его, вы можете ожидать, что они попробуют все . В самом деле. Все. Чтобы предотвратить самые очевидные попытки, я «заблокировал» некоторые маршруты. Fortune.js встраивает экспресс, так что было легко запретить людям пробовать звонки на / cell или / users . Также, просто добавив .readOnly()ресурс в Fortune.js, он разрешает только GETзапрос к нему.

Извините, если вы пытались изменить лабиринт, но мы не могли позволить вам сделать это;)

Что случилось в день Д?

Мы запустили APIbunny .com в пятницу. Хотя наш программный запуск на Hacker News не совсем сработал, как мы и ожидали, мы получили большой интерес со стороны сообщества API — особенно от APIscene.com и группы Api-Craft .

Мы получили более 4000 посещений в первый день, более 1000 посещений на страницах-победителях, которыми поделились хакеры. Только 30 человек решили это до сих пор. Вы можете видеть живые статистику на общественной приборной панели питается от Keen.io .

Поздравляем Керна Паттона с получением первого приза за билет на следующую конференцию API Strategy & Practice Conference (APIStrat) в Чикаго в сентябре. Остальные выиграли 3-х уровневую добычу и скидочный билет на APIStrat.

Мы также хотим выделить других хакеров, которые поделились своим решением на github

Теперь код APIbunny доступен на Github , не стесняйтесь изменять его и писать клиентам, мы поделимся им здесь.

Особое упоминание Стиву Уилмотту за открытость в создании проекта такого типа, Ванессе Рамос за работу с социальными медиа на месте в течение дня запуска и всей команде 3scale по бета-тестированию APIbunny .