Skip to content

REST service on Go: create, get by query, patch, delete for tasks. With correct processing concurrency on it.

Notifications You must be signed in to change notification settings

forIinRanger/taskRestAPI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tasks API - Техническое задание

Общее описание проекта

Вам необходимо создать простое REST API для управления задачами (todo-списком) на языке Go. Это учебный проект для отработки основных навыков веб-разработки на Go.

Основные цели проекта

  • Изучить создание HTTP API на Go
  • Отработать работу с JSON
  • Освоить валидацию данных
  • Изучить фильтрацию, поиск и пагинацию
  • Понять основы конкурентной безопасности
  • Написать базовые тесты

Технические требования

Стек технологий

  • Язык: Go 1.21+
  • Хранилище: В памяти приложения (данные теряются при перезапуске)
  • Формат данных: JSON
  • Порт: Переменная окружения PORT (по умолчанию 8080)

Запуск приложения

# Установка переменной окружения (опционально)
export PORT=3000

# Запуск приложения
go run main.go

Модель данных

Структура задачи (Task)

{
  "id": "0d3f2b71-8aa0-4f6a-9d0a-6c2a40c2b1ad",
  "title": "Написать API спецификацию",
  "content": "Создать техническое задание для Tasks API",
  "status": "in_progress",
  "priority": "high",
  "tags": ["работа", "документация"],
  "dueDate": "2025-09-20T12:00:00Z",
  "createdAt": "2025-09-13T06:00:00Z",
  "updatedAt": "2025-09-13T06:30:00Z"
}

Описание полей

Поле Тип Описание Ограничения
id string Уникальный идентификатор UUID v4, генерируется автоматически
title string Название задачи Обязательное, 1-200 символов
content string Описание задачи 0-5000 символов
status string Статус задачи todo, in_progress, done (по умолчанию todo)
priority string Приоритет low, normal, high (по умолчанию normal)
tags array Теги Максимум 10 тегов, каждый 1-32 символа
dueDate string|null Дедлайн RFC3339 формат или null
createdAt string Время создания RFC3339, генерируется автоматически
updatedAt string Время обновления RFC3339, обновляется автоматически

API Endpoints

1. Создание задачи

POST /tasks

Создает новую задачу в системе.

Тело запроса:

{
  "title": "Купить молоко",
  "content": "Не забыть купить молоко по дороге домой",
  "priority": "high",
  "tags": ["дом", "покупки"],
  "dueDate": "2025-09-14T18:00:00Z"
}

Успешный ответ (201 Created):

{
  "id": "generated-uuid-here",
  "title": "Купить молоко",
  "content": "Не забыть купить молоко по дороге домой",
  "status": "todo",
  "priority": "high",
  "tags": ["дом", "покупки"],
  "dueDate": "2025-09-14T18:00:00Z",
  "createdAt": "2025-09-13T10:00:00Z",
  "updatedAt": "2025-09-13T10:00:00Z"
}

Заголовки ответа:

  • Location: /tasks/{id}
  • Content-Type: application/json

2. Получение списка задач

GET /tasks

Возвращает список задач с возможностью фильтрации, поиска и пагинации.

Параметры запроса:

Параметр Тип Описание Пример
status string Фильтр по статусу ?status=todo
tag string Фильтр по тегу (можно несколько) ?tag=работа&tag=срочно
q string Поиск по названию и содержанию ?q=отчет
sort string Сортировка по приоритету ?sort=priority,desc
page int Номер страницы ?page=2
pageSize int Размер страницы (1-100) ?pageSize=10

Пример запроса:

GET /tasks?status=todo&tag=работа&q=отчет&sort=priority,desc&page=1&pageSize=10

Успешный ответ (200 OK):

{
  "items": [
    {
      "id": "uuid-1",
      "title": "Написать отчет",
      "content": "Квартальный отчет по продажам",
      "status": "todo",
      "priority": "high",
      "tags": ["работа", "отчеты"],
      "dueDate": "2025-09-15T17:00:00Z",
      "createdAt": "2025-09-13T09:00:00Z",
      "updatedAt": "2025-09-13T09:00:00Z"
    }
  ],
  "page": 1,
  "pageSize": 10,
  "total": 25,
  "totalPages": 3
}

3. Получение задачи по ID

GET /tasks/{id}

Возвращает конкретную задачу по её идентификатору.

Успешный ответ (200 OK):

{
  "id": "uuid-here",
  "title": "Написать отчет",
  "content": "Квартальный отчет по продажам",
  "status": "in_progress",
  "priority": "high",
  "tags": ["работа"],
  "dueDate": "2025-09-15T17:00:00Z",
  "createdAt": "2025-09-13T09:00:00Z",
  "updatedAt": "2025-09-13T11:30:00Z"
}

Ошибка (404 Not Found):

{
  "error": {
    "code": "not_found",
    "message": "Task not found",
    "details": []
  },
  "requestId": "req-12345"
}

4. Обновление задачи

PATCH /tasks/{id}

Частично обновляет существующую задачу.

Тело запроса (любые поля):

{
  "status": "in_progress",
  "tags": ["работа", "срочно"]
}

Успешный ответ (200 OK): Полный объект задачи с обновленными полями и новым updatedAt.

5. Удаление задачи

DELETE /tasks/{id}

Удаляет задачу из системы.

Успешный ответ (204 No Content): Пустое тело ответа.

Обработка ошибок

Коды состояния HTTP

Код Описание Когда используется
200 OK Успешное чтение или обновление
201 Created Успешное создание
204 No Content Успешное удаление
400 Bad Request Неверный JSON или параметры
404 Not Found Ресурс не найден
422 Unprocessable Entity Ошибки валидации
500 Internal Server Error Внутренняя ошибка сервера

Формат ошибок

Все ошибки возвращаются в едином JSON формате:

{
  "error": {
    "code": "validation_error",
    "message": "Ошибка валидации данных",
    "details": [
      {
        "field": "title",
        "rule": "required",
        "message": "Поле title обязательно для заполнения"
      },
      {
        "field": "tags",
        "rule": "max_length",
        "message": "Максимальное количество тегов - 10"
      }
    ]
  },
  "requestId": "req-67890"
}

Типы ошибок

  • invalid_json - Неверный формат JSON
  • validation_error - Ошибки валидации полей
  • not_found - Ресурс не найден
  • bad_request - Неверные параметры запроса
  • internal - Внутренняя ошибка сервера

Правила валидации

При создании (POST)

  • title - обязательное поле, 1-200 символов
  • content - 0-5000 символов
  • status - только todo, in_progress, done
  • priority - только low, normal, high
  • tags - массив до 10 элементов, каждый 1-32 символа
  • dueDate - корректная дата в формате RFC3339

При обновлении (PATCH)

Те же правила, но все поля опциональны (кроме валидации значений).

Обработка тегов

  • Убираются ведущие и замыкающие пробелы
  • Удаляются дубликаты
  • Пустые строки после обрезки пробелов - ошибка

Примеры использования с curl

Создание задачи

curl -X POST http://localhost:8080/tasks \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Изучить Go",
    "content": "Пройти туториал по основам Go",
    "priority": "high",
    "tags": ["обучение", "программирование"]
  }'

Получение списка задач

curl "http://localhost:8080/tasks?status=todo&tag=работа&page=1&pageSize=5"

Обновление задачи

curl -X PATCH http://localhost:8080/tasks/uuid-here \
  -H "Content-Type: application/json" \
  -d '{"status": "in_progress"}'

Удаление задачи

curl -X DELETE http://localhost:8080/tasks/uuid-here

Архитектура приложения

Рекомендуемая структура

project/
├── main.go                 # Точка входа
├── internal/
│   ├── handler/           # HTTP обработчики
│   │   └── task.go
│   ├── service/           # Бизнес-логика
│   │   └── task.go
│   ├── store/             # Хранилище данных
│   │   └── memory.go
│   └── model/             # Модели данных
│       └── task.go
└── README.md

Слои приложения

  1. Handler - обрабатывает HTTP запросы, парсит JSON, возвращает ответы
  2. Service - содержит бизнес-логику, валидацию, координирует работу
  3. Store - работает с хранилищем данных (интерфейс для будущей замены)

Конкурентная безопасность

  • Используйте sync.RWMutex для защиты данных
  • Операции чтения - RLock()
  • Операции записи - Lock()
  • Для списков делайте копию данных под блокировкой, затем обрабатывайте без неё

Тестирование

Минимальные требования

  • Покрытие кода тестами не менее 10%
  • Использование httptest для тестирования HTTP handlers
  • Запуск тестов с флагом -race для выявления гонок данных

Обязательные тест-кейсы

POST /tasks:

  • ✅ Успешное создание
  • ❌ Неверный JSON (400)
  • ❌ Нарушение валидации (422)

GET /tasks:

  • ✅ Получение всех задач
  • ✅ Фильтрация по статусу
  • ✅ Фильтрация по тегам
  • ✅ Поиск по содержимому
  • ✅ Сортировка по приоритету
  • ✅ Пагинация

GET /tasks/{id}:

  • ✅ Найдена (200)
  • ❌ Не найдена (404)

PATCH /tasks/{id}:

  • ✅ Успешное обновление (200)
  • ❌ Задача не найдена (404)
  • ❌ Ошибка валидации (422)

DELETE /tasks/{id}:

  • ✅ Успешное удаление (204)
  • ❌ Задача не найдена (404)

Пример теста

func TestCreateTask(t *testing.T) {
    tests := []struct {
        name           string
        requestBody    string
        expectedStatus int
    }{
        {
            name:           "valid task",
            requestBody:    `{"title":"Test task"}`,
            expectedStatus: 201,
        },
        {
            name:           "missing title",
            requestBody:    `{"content":"No title"}`,
            expectedStatus: 422,
        },
    }
    
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            // Тест логика здесь
        })
    }
}

Логирование

Для каждого HTTP запроса логируйте:

  • HTTP метод
  • Путь запроса
  • Код ответа
  • Время выполнения
  • Уникальный ID запроса

Пример лога:

2025-09-13T10:30:45Z INFO [req-12345] POST /tasks - 201 - 15ms

Graceful Shutdown

Реализуйте корректное завершение работы:

  • Обработка сигналов SIGTERM и SIGINT
  • Завершение обработки текущих запросов
  • Закрытие всех ресурсов
  • Отсутствие зависших горутин

Дополнительные требования

Документация

  • README.md с инструкциями по запуску
  • Примеры использования API
  • Данная спецификация в репозитории

Качество кода

  • Использование go fmt
  • Проверка go vet
  • Идиоматичный Go код
  • Обработка всех ошибок

Критерии оценки

Обязательный минимум (удовлетворительно)

  • ✅ Все эндпоинты реализованы и работают
  • ✅ Корректные HTTP коды ответов
  • ✅ Базовая валидация данных
  • ✅ Простые тесты присутствуют

Хорошая работа

  • ✅ + Полная фильтрация и поиск
  • ✅ + Правильная пагинация
  • ✅ + Единый формат ошибок
  • ✅ + Конкурентная безопасность

Отличная работа

  • ✅ + Comprehensive тесты (покрытие >50%)
  • ✅ + Graceful shutdown
  • ✅ + Качественная архитектура

Удачи в разработке! 🚀

About

REST service on Go: create, get by query, patch, delete for tasks. With correct processing concurrency on it.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages