Full stack проект на Go за неделю

Разработка /
Разработка: Full stack проект на Go за неделю
Этой серией постов мы охватим создание full stack проекта на языке Go (golang).

Наш проект: Конвертер валют


Из названия в принципе понятно, что будет делать приложение — конвертация валют. Реальное, полезное, удобное приложение — что ещё нужно для хорошего примера?

Мы разделим приложение на отдельные части, дабы проще уместить проект в серию статей и постепенно наращивать сложность.


День первый. Определяемся с бэкендом и API


Сегодня мы должны определиться с тем, что мы хотим от нашего приложения и API, какие технологии используем для его построения и т.д. С этим фундаментом мы и начнём реализацию.

Главная идея сервиса — предоставить API для массовой конвертации сумм в разных валютах. Кроме того, мы создадим систему настройки веб-хуков для оповещений об изменении курса валют.
Для веб-сайта и мобильных приложений нам нужен способ получения всех курсов валют (во фронтенде будет происходить расчёт и конвертация) и способ получения истории изменения курса каждой валюты.

Получение валют

Первая проблема — где брать актуальные курсы валют. На самом деле проблем с валютами намного больше: это и разница между курсами покупки/продажи, это и отношение курсов между разными валютами, и т.д., но мы не будем сейчас вдаваться в детали — нам просто нужен достоверный источник актуальных курсов валют.

И Европейский Центральный Банк (ECB) как раз предоставляет курсы валют в формате XML со своих серверов. XML файл мы можем получить через HTTP и это полностью нас устраивает на данный момент. В ECB нет курсов всех валют мира, но сейчас для нас это также не имеет значения.

Их XML файл выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
  <gesmes:subject>Reference rates</gesmes:subject>
  <gesmes:Sender>
    <gesmes:name>European Central Bank</gesmes:name>
  </gesmes:Sender>
  <Cube>
    <Cube time='2016-04-01'>
      <Cube currency='USD' rate='1.1432'/>
      <Cube currency='JPY' rate='128.07'/>
      <Cube currency='BGN' rate='1.9558'/>
      <Cube currency='CZK' rate='27.030'/>
      <Cube currency='DKK' rate='7.4503'/>
      <Cube currency='GBP' rate='0.79890'/>
      <Cube currency='HUF' rate='313.30'/>
      <Cube currency='PLN' rate='4.2440'/>
      <Cube currency='RON' rate='4.4693'/>
      <Cube currency='SEK' rate='9.2413'/>
      <Cube currency='CHF' rate='1.0946'/>
      <Cube currency='NOK' rate='9.4401'/>
      <Cube currency='HRK' rate='7.5105'/>
      <Cube currency='RUB' rate='77.5430'/>
      <Cube currency='TRY' rate='3.2285'/>
      <Cube currency='AUD' rate='1.4884'/>
      <Cube currency='BRL' rate='4.1296'/>
      <Cube currency='CAD' rate='1.4894'/>
      <Cube currency='CNY' rate='7.3903'/>
      <Cube currency='HKD' rate='8.8652'/>
      <Cube currency='IDR' rate='15007.54'/>
      <Cube currency='ILS' rate='4.3182'/>
      <Cube currency='INR' rate='75.8528'/>
      <Cube currency='KRW' rate='1315.78'/>
      <Cube currency='MXN' rate='19.8996'/>
      <Cube currency='MYR' rate='4.4382'/>
      <Cube currency='NZD' rate='1.6518'/>
      <Cube currency='PHP' rate='52.615'/>
      <Cube currency='SGD' rate='1.5389'/>
      <Cube currency='THB' rate='40.115'/>
      <Cube currency='ZAR' rate='16.8758'/>
    </Cube>
  </Cube>
</gesmes:Envelope>

Структура файла предельно проста — он содержит даже дату курсов. Единственное, чего не хватает, это полного названия валют. Но это мы поправим в своём приложении.

Мы можем получать курсы валют по HTTP раз в день, в принципе, этого будет достаточно. Но было бы желательно сделать вариант загрузки курсов с учётом временных зон и настраиваемой частотой загрузки — возможно, даже раз в час.

При получении данных по валютам, мы должны их обработать (вообще, конечно, можно обойтись без этого и прямо выдавать сырые данные, но это не очень хорошо) и положить в какое-то постоянное место хранения.

Всё это будет выполняться скриптом в фоне — это не часть бэкенда, с которой кто-нибудь будет работать напрямую, оно просто должно работать когда нужно.

API

Здесь мы опишем, что хотим от API. В первую очередь, все конечные точки должны возвращать данные в формате JSON.

/currencies GET, POST

Эта конечная точка возвратит JSON-представление всех валют. При GET-запросе будут получены данные относительно базовой валюты (EUR), а запрос POST будет принимать параметр с наименованием базовой валюты, после чего будет проведён соответствующий расчёт.

Содержание POST-запроса с передачей базовой валюты Британского фунта будет таким:

{
  "base_currency": "GBP"
}

Ответ сервера и на POST и на GET запросы будет следующим:

{
  "currency_date": "2016-04-01",
  "base_currency": "GBP",
  "rates": [
    {
      "name": "USD",
      "rate": 1,43097
    },
    {
      "name": "DKK",
      "rate": 9,32570
    },
    ...
  ]
}


/convert POST

Эта конечная точка будет конвертировать некоторые суммы (возможно, всего одну) из одной валюты в другую. Запрос будет выглядеть примерно так:

{
  "target_currency": "USD",
  "base_currency": "GBP",
  "amounts": [
    14,
    9,
    4.3125,
    5.5,
    ...
  ]
}

В ответе будет сохранён такой же порядок сумм:

{
  "base_currency": "GBP",
  "target_currency": "USD",
  "currency_date": "2016-04-01",
  "converted_amounts": [
    9.783590,
    6.289451,
    3.013695,
    3.843553,
    ...
  ]
}


/webhook POST, DELETE

С помощью этой конечной точки мы будем добавлять и удалять веб-хуки. При её вызове необходимо учитывать, что переданный URL способен принимать POST-запрос и отвечать в JSON.
POST-запрос будет примерно таким:

{
  "base_currency": "USD",
  "url": "http://some.exampleserver.foo/currency/webhook",
  "token": "somemagickeyword"
}

При добавлении новых курсов, бэкенд выполнит POST-запрос на этот URL, в котором будет необходимый курс валюты и дополнительный заголовок Authorization с настроенным токеном (для безопасности, чтобы никто посторонний не мог делать POST-запросы на этот URL).

Что дальше?


Программирование!

Далее мы выберем среду разработки и стек для деплоя, затем примемся за разработку.

Второй день
0 комментариев
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.