# Соглашения и code style
# Общие рекомендации
- Работая с кодом, стремитесь повышать его качество. Если быстрый фикс ухудшает качество кода, запланируйте рефакторинг.
- Помните, ваш код должен быть понятен не только вам, но и коллегам. Красота скрывается в простоте (opens new window).
- Предпочитайте композицию вместо наследования (opens new window).
- Остерегайтесь сразу создавать переиспользуемые компоненты (Reusable components)]. Лишний слой абстрации переусложнит его использование сейчас.
# Комментирование
- Комментарии пишем на русском языке.
- Пишите в комментариях моменты, которые не очевидны при чтении кода, пеерчисление сайд-эффектов.
- Высокоуровневые комментарии класса/модуля не должны описывать детали реализации. Если у класса есть отдельно интерфейс, комментарии пишите в интерфейсе.
- Низкоуровневые комментарии описывают описывают код и должны отвечать на вопросы: "Что?" и "Почему?", а не "Как?".
- Если багфикс требует написание сложного кода, в комментарии поставьте также номер задачи из JIRA.
- Обновляйте комментарии одновременно с кодом, не дублируйте.
# API
# REST API
# Документирование
Используем swagger/openapi формат.
# Версионирование
Номер версии указываем в префиксе:
GET /api/v1/
GET /api/v2/
Используем только мажорные версии. Недопустимо переименовывать методы или параметры в рамках одной версии.
Если необходимо поменяется параметр, номер версии должен быть повышен и предусмомотрена обратная совместимость в предыдущей версии API.
# Именование endpoint'ов
Имя коллекций в множественном числе:
GET /campaigns
GET /campaigns/123
Используйте вложенность, чтобы показать связанность объектов:
GET /campaigns/123/webhook/1
# Методы endpoint'ы
В именах endpoint'ов должны быть только существительные. Действие определяют http-методы:
HEAD /offers/123 # возвращает только HTTP заголовки, без body
GET /offers/123 # запрос оффера с ID 123
DELETE /offers/123 # удаление оффера
POST /offers # создание нового оффера
PUT /offers/123 # модификация оффера ID 123
PATCH /offers/123 # модификация только определенных параметров оффера
Если над объектом производится специфические действия, допустимо добавлять глаголы:
PUT /offers/123/disable
# Заголовки
Используем стандартные HTTP коды (opens new window). Наиболее используемые:
200 - все ок
202 - действие принято, но будет выполнено позже
400 - в запросе переданы некорректные параметры
401 - необходима авторизация
402 - оплаченный период закончен или данное действие недоступно в текущей редакции
403 - с текущей авторизацией доступ к объекту запрещен
404 - endpoint'а или объекта не существует
405 - передан некорректный метод для endpoint'аe
406 - неприемлемый запрос, ошибка валидации, переданы некорректные данные
429 - превышен лимит запросов
# Ошибки
Передавайте в ответе текст ошибки:
{
"error" => "This campaign is already started"
}
Расширенный вариант:
{
"error" => "This campaign is already started",
"code" => "campaign_started",
"documentation_url": "https://developer.github.com/v3"
}
# Параметры:
sort
- сортировка (по умолчанию asc):GET /offers?sort=name
GET /offers?sort=name:asc GET /offers?sort=name:desc
GET /offers?sort=name:asc,country:desc
offset
иlimit
для пагинации:GET /offers?offset=10&limit=10
filter
для фиграции:GET /offers?filter
Даты в формате ISO 8601: YYYY-MM-DDTHH:MM:SSZ
.
# Лимитирование запросов
Если у API есть лимит запросов, в ответе нужно передавать следующие заголовки:
X-RateLimit-Limit
- какое есть ограничение (число)X-RateLimit-Remaining
- сколько осталось до достижение лимита (число)X-RateLimit-Reset
- сколько секунд (opens new window) осталось до сброса ограничений
# Логирование
- Обязательно должен вестись лог запросов к API и ответов. Все персональные данные и пароли нужно фильтровать.
# Мониторинг
# Health-checks
- Опишите entryoint для проверки состояния приложения (читайте о livenessPrope (opens new window))
- Если приложению нужно время для разогрева прежде, чем он сможет обслуживать трафик, опишите readinessProbe (opens new window)
# Бизнес метрики
Читайте про выгрузку метрик в Prometheus (opens new window).
WARNING
Убедитесь, что метрики недоступны извне и запрещен к ним доступ через ingress.
# JavaScript
Смотрите /dev/cs/js.html
# PHP
- Follow PSR-2 (opens new window) and PSR-12 (opens new window) conventions.
- Use PHP_CS and PHPStan.
# Strict Types и Type Hinting
Включаем строгую типизацию:
declare(strict_types=1);
Список type hinting по версиям PHP https://mlocati.github.io/articles/php-type-hinting.html (opens new window).
# Ruby
A community-driven Ruby coding style guide (opens new window).
# Golang
# Рекомендации по коду
- Используем Go Modules.
- Вендерим зависимости (opens new window)..
- Используем GolangCI Lint (opens new window).
- Тесты храним в тех же директориях, что и код. Т.е. не в
tests/
. - Именовать папки предпочитаем по соглашению golang-standards/project-layout (opens new window).
- Подключите в проекте пакет uber-go/automaxprocs (opens new window).
- Чтобы избежать циклических зависимостей для связи между пакетов используем интерфейсы, модели и константы
- Для работы со внешними источниками используем адаптеры. Они не должны содержать бизнес логику, только методы повторяющие методы на внешних компонентах. К адаптерам пишем интерфейсы и используя интерфейсы инжектим их там где они нужны.
- Для сложных конструкторов пишем фабрики.
- Сервисы пишем отдельно и весь код в сервисах должен быть чистыми функциями.
- Для работы с данными используем репозитории. При этом инжектим внутрь репозитория источник данных.
- Модели должны быть тонкими, не содержать бизнес логику.
- Избегайте глобальных переменных.
# Рекомендуемые пакеты
- Для логирования https://github.com/sirupsen/logrus
- Для роутинга https://github.com/gorilla/mux
- Для работы с env переменными https://github.com/caarlos0/env и https://github.com/joho/godotenv
- Для генерации интерфейсов https://github.com/vburenin/ifacemaker
- Для генерации моков к интерфейсам https://github.com/vektra/mockery
- Для проверки значений в тестах https://godoc.org/github.com/stretchr/testify/assert
- Для использования моков https://godoc.org/github.com/stretchr/testify/mock (Если есть mock SomeStructMock делаем
SomeStructMock.On("SomeMethod", mock.AnythingOfType("*models.ParamTypeStruct")).Return(mockedValue, err).Once()
)
Почитать:
- Effective Go (opens new window).
- Opinionated Styleguide for the Go language (opens new window).
- Для документирования API используем Swagger, рекомендуется Swag (opens new window).
# Shell
Google Shell Style Guide (opens new window).
# Makefile
- Рекомендуем заводить Makefile в каждом проекте, с унифицированными командами
make dev
,make test
. - Рекомендуемое имя файла
Makefile
. - Имя таргетов через
-
. Например,run-tests
. Начинаем с глагола:apply-
,create-
,install-
и т.д.. - Переменные окружения пишем в верхнем регистре. Пример,
PROJECT_PATH
- Локальные переменные в нижнем с разделителем
_
. Пример,build_dir = $(PROJECT_PATH)/build
- Добавьте команду
make help
:
help: ## Display this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-10s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
test: ## Run tests
go test ./..
# Книги
← Контент