Лёгкое REST API для задач на Go: in-memory хранилище, валидация, логирование, graceful shutdown
Разработать REST API на Go для управления сущностями Тask с асинхронным логированием действий через канал.
Функционал:
GET /tasks получить список задач (фильтрация по статусу)
GET /tasks/{id} — получить задачу по ID
- POST /tasks создать задачу
Требования:
- Структура Тask и формат логов усмотрение на свое
Асинхронное логирование (через канал и отдельную горутину)
Чистая архитектура
Только стандартные библиотеки (net/http, sync, context и пр.)
- Хранилище іп-тетогу (своя реализация, без готовых библиотек)
- Поддержка graceful shutdown
README.md с инструкцией по сборке и запуску
- Создать задачу - POST /tasks
- Получить задачу по ID - GET /tasks/{id}
- Список по статусу + пагинация - GET /tasks?status=...&limit=...&offset=...
- Валидация входных данных
- Асинхронный логгер с middleware на запросы
- Graceful shutdown
- Go 1.22+, проект написан и протестирован на Go 1.24.4
- Весь проект на встроенных библиотеках
.
├── cmd/app # main.go (запуск сервера)
├── internal
│ ├── api
│ │ ├── dto # DTO запросов и ответов
│ │ ├── handlers # Router-структура + хендлеры
│ │ ├── mappers # model -> DTO
│ │ └── validation # валидация DTO
│ ├── core
│ │ ├── logger # асинхронный логгер + middleware
│ │ ├── models # доменные модели (Task, Status)
│ │ └── storage # in-memory Storage с RWMutex
│ └── utils # WriteJSON, graceful run
├── Makefile
├── Dockerfile
└── go.mod
go run ./cmd/main.go
# или
make run
Сервер слушает :8080
.
Создать задачу:
Request
{
"name": "Buy milk",
"status": "new"
}
201 response
{
"id": 1,
"name": "Buy milk",
"status": "new",
"created_at": "2025-08-13T12:34:56Z"
}
Получить задачу по ID:
200 response
{
"id": 1,
"name": "Buy milk",
"status": "new",
"created_at": "2025-08-13T12:34:56Z"
}
Список задач по статусу:
200 response
"items": [
{ "id": 1, "name": "Buy milk", "status": "new", "created_at": "..." }
],
"total": 1
}
Статусы: new
, in_progress
, done
, можно изменить в internal/core/models/task.go
, не забудьте обновить валидацию в internal\api\validation\validator.go
Прогнать все тесты:
make test
# под капотом: go test ./... -v
В проекте есть готовая коллекция для Postman — task-api.postman_collection.json
make build
# бинарник: bin/server
Собрать и запустить:
make docker-build
make docker-run
# или
docker build -t task-api:latest .
docker run --rm -p 8080:8080 task-api:latest
Сервис ловит SIGINT/SIGTERM, перестает принимать новые соединения и ждёт активные запросы до таймаута (по умолчанию 15s). Логи старт/стоп и ошибки выводятся через асинхронный логгер.
# создать
curl -s -X POST http://localhost:8080/tasks \
-H 'Content-Type: application/json' \
-d '{"name":"Buy milk","status":"new"}' | jq
# получить по id
curl -s http://localhost:8080/tasks/1 | jq
# список по статусу
curl -s 'http://localhost:8080/tasks?status=new&limit=10&offset=0' | jq
-
Валидация и нормализация query: limit - дефолт 50, максимум 200, offset - неотрицательный.
-
Хранилище - RWMutex, пагинация на срезе после фильтра.
-
Логирование:
- middleware пишет метод, путь, статус и длительность
- хендлеры логируют валидаторные 4xx как Info, 5xx как Error, бизнес-события - Info