Golang Application Template

Here is my template for Golang Application – https://github.com/ildarusmanov/gobase https://github.com/wajox/gobase

Only one thing that you have to do after git clone – replace all package name entries, from github.com/ildarusmanov/gobase github.com/wajox/gobase to [your_package_name]

UPD:

Template has been updated and moved into wajox/gobase repository.

KrakenD config example

What is KrakenD?

KrakenD is your self-designed REST API Gateway that feeds from your existing data services (Your APIs, legacy, cloud, IoT…) Just define visually or in a configuration file the endpoints your applications will use and the KrakenD will fetch and transform the content at your will for you.

https://www.krakend.io

Configuration example(proxy for POST, GET requests):

{
  "version": 2,
  "extra_config": {
    "github_com/devopsfaith/krakend-gologging": {
      "level": "WARNING",
      "prefix": "[KRAKEND]",
      "syslog": false,
      "stdout": true
    },
    "github_com/devopsfaith/krakend-metrics": {
      "collection_time": "60s",
      "proxy_disabled": false,
      "router_disabled": false,
      "backend_disabled": false,
      "endpoint_disabled": false,
      "listen_address": ":8090"
    },
    "github_com/devopsfaith/krakend-cors": {
      "allow_origins": [ "*" ],
      "allow_methods": [ "POST", "GET", "PUT", "DELETE" ],
      "allow_headers": [
        "Origin",
        "Authorization",
        "Content-Type",
        "Accept",
        "X-Auth-Token"
      ],
      "expose_headers": [ "Content-Length" ],
      "max_age": "12h"
    }
  },
  "timeout": "3000ms",
  "cache_ttl": "300s",
  "output_encoding": "no-op",
  "name": "api-proxy",
  "port": 80,
  "endpoints": [
    {
      "endpoint": "/",
      "extra_config": {},
      "output_encoding": "no-op",
      "concurrent_calls": 1,
      "backend": [
        {
          "url_pattern": "/",
          "encoding": "no-op",
          "extra_config": {},
          "sd": "static",
          "host": [
            "http://some-landing"
          ],
          "disable_host_sanitize": false
        }
      ]
    },
    {
      "method": "GET",
      "endpoint": "/api/v1/endpoint}",
      "extra_config": {},
      "output_encoding": "no-op",
      "concurrent_calls": 1,
      "backend": [
        {
          "method": "POST",
          "url_pattern": "/api/v1/{endpoint}",
          "encoding": "no-op",
          "extra_config": {},
          "sd": "static",
          "host": [
            "http://backend-service-getter"
          ],
          "disable_host_sanitize": false
        }
      ]
    },
    {
      "method": "POST",
      "endpoint": "/api/v1/endpoint}",
      "extra_config": {},
      "output_encoding": "no-op",
      "concurrent_calls": 1,
      "backend": [
        {
          "method": "POST",
          "url_pattern": "/api/v1/{endpoint}",
          "encoding": "no-op",
          "extra_config": {},
          "sd": "static",
          "host": [
            "http://backend-service-poster"
          ],
          "disable_host_sanitize": false
        }
      ]
    },
}

docker-compose bind volume

Необходимо было разобраться с тем как сделать bind volume в 3+ синтаксисе docker-compose, решение ниже:

При поднятии приложения нужно устанавливать переменную окружения APPROOT, которая указывает на корневую директорию приложения:

APPROOT=[local source path] docker-compose up -d

Проектирование Web API

Одним из самых распространенных подходов при проектировании API является REST API, что такое REST API можно узнать здесь.

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

Перейдем к принципам, поскольку для REST используется протокол HTTP, то он силньо завязан на его особенностях и в частности на адресе URL.

URL

Чтобы ваш API было легче понимать уделите особое внимание идентификаторам ваших ресурсов(URI):

  1. делайте минимальными и понятными(краткое название ресурса);
  2. абстрактные ресурсы лучше заменить на конкретные(/videos вместо /items)
  3. не используйте в них глаголы, вместо них используйте HTTP методы (POST, PUT, GET, PATCH, DELETE);
  4. используйте в названии только множественное или только единственное число для ресурсов во всем проекте;
  5. используйте не более двух адресов на один ресурс (/videos и /videos/{id});
  6. для вложенных ресурсов используйте URL вида /videos/{id}/comments;
  7. используйте простые и прозрачные имена в параметрах запросов после знака “?”;

Ошибки

Всегда обрабатывайте ошибки и сообщайте о них клиенту, используйте соответствующие коды статуса ответа HTTP, также сопровождайте ошибки описанием в теле ответа, возвращайте внятное текстовое описание ошибки.

Версии

Всегда версионизируйте API, например с помощью префикса /v1 или в заголовках и поддерживайте как минимум две последнии версии. Это позволит вашим клиентам плавно и без проблем переходить на новые версии вашего API.

Пагинация и поля ответа

Испольуйте для пагинации параметры limit и offset, не забывайте возвращать в ответе общее количество доступных ресурсов.

Клиентам не всегда нужны все доступные поля, потому предусмотрите возможность кастомизации списка возвращаемых полей параметром fields.

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

API субдомен

Выделите для вашего API отдельный субдомен(например api.example.com/v{version_id}) и сосредоточьте все ваше API в зоне этого субдомена.

Формат

Для передачи формата входных и получаемых данных указывайте формат в виде расширения файла(например /v1/videos.json) и обеспечьте поддержку нескольких форматов данных.

Интеграция и документация

Напишите SDK или библиотеки для платформ, которые используют ваши клиенты. Cопроводите это все качественными и подробными примерами использования вашего API и документацией по использованию ваших инструментов и API.