## Строгие правила checkstyle и статического анализа
Код должен соотвествовать наиболее строгим правилам checkstyle и проверяться всеми статистическими анализаторами arcadia (на текущий момент это только ERROR_PRONE).

## Стандартное расположение файлов (layout)

Допустимо две структуры файлов:

* Arcadia-style (рекомендуется к использованию)
На верхнем уровне есть:
ya.make
директория src, внутри которой исходники и ресурсы (без package-prefix'а)
директория ut, внутри которой ya.make тестов и исходники тестов в ut/src
Пример структуры директорий можно посмотреть тут: https://a.yandex-team.ru/arc/trunk/arcadia/solomon/libs/java/yandex/blackbox

* Maven-style
В директории есть
ya.make - описание сборки и зависимостей модуля
ut/ya.make - описание сборки и зависимостей тестов
src/main/java - директория с исходниками
src/main/resources - директория с ресурсами
src/test/java - директория с исходниками тестов
src/test/resources - директория с ресурсами тестов
Пример структуры директорий можно посмотреть тут: https://a.yandex-team.ru/arc/trunk/arcadia/direct/libs/model

## Документация
Библиотека должна быть хорошо документирована:
- README.md в корне проекта с общим описание, мотивацией, примерами использования
- Javadoc'и на все публичные классы и публичные методы больше 1 строки
- Код должен быть размечен аннотациями из JSR-305 (`@Nullable`/`@NotNull`, `@ThreadSafe`, `@WillClose`/`@WillNotClose`, ...)
- Все комментарии и документации на английском языке

## Тесты
Функциональность библиотеки должна быть хорошо покрыта тестами. В качестве тестового фреймворка нужно использовать JUnit, для тестирования клиентов не рекомендуется использовать mock'и: лучше всего поднимать сам сервис из рецепта (благо, в аркадии это несложно), либо поднимать в тесте stub сервиса.

## Зависимости
Для клиентов будет узкий список разрешённых к использованию библиотек (в частности, нельзя использвать библиотеки из проектов). Хочется, чтобы для каждой задачи была примерно одна разрешённая библиотека. Версии библиотек будут зафиксированы в едином списке DEPENDENCY_MANAGEMENT.

# Минимальность зависимостей
Даже из разрешённых библиотек не стоит тащить в зависимости всё, что можно. Не стоит подключать библиотеку, если её функциональность есть в JDK (пусть и использование чуть многословней). В частности, клиент не должен зависеть ни от какого DI-фреймворка. Если хочется предоставлять готовую интеграцию, нужно сделать для этого отдельную библиотеку с зависимостями на исходную и, к примеру, Spring.

# Логирование
Должно быть. Использовать нужно slf4j, бекенды и их конфиги добавлять не нужно.

# Concurrency
Клиенты должны быть потоко-безопасны.
Если клиенту нужен ThreadPool, должна быть возможность передать его снаружи.
Если создаётся дефолтный ThreadPool, потоки должны иметь понятные имена.
Запрещено использовать `CommonForkJoinPool` (например из `stream().parallel()`). Если есть такая необходимость, должна быть возможность передать собственный ForkJoinPool.

## Асинхронность
Клиенты должны предоставлять асинхронный интерфейс на CompleteableStage.
Синхронный интерфейс может предоставляться для удобства, как обёртка над асинхронным.

## HTTP-клиент
Во всех клиентах нужно использовать одинаковый HTTP-клиент.
На текущий момент предлагается использовать async-http-client.
Когда HttpClient из JDK выйдет из инкубатора, мы его потестируем и, возможно, сделаем основным.
Клиенты должны предоставлять возможность передавать HTTP-клиент извне.

## Интерфейс
Должны быть методы без встроенных в реализацию ретраев, чтобы пользователи могли поверх написать любую удобную им.
Методы с политикой перезапросов могут быть в качестве предлагаемого решения для ретраев по умолчанию.
Библиотека должна допускать лёгкое написание обёртки с трейсингом и мониторингом.
