songl 5460bf2019 | ||
---|---|---|
.idea | ||
bruno | ||
cmd | ||
config | ||
controllers | ||
database | ||
domain | ||
middleware | ||
repositories | ||
routes | ||
services | ||
utils | ||
README.md | ||
docker-compose.yml | ||
go.mod | ||
go.sum |
README.md
Документация API
Обзор
Этот проект представляет собой RESTful API для управления пользователями и Todo пользователей. В качестве ORM используется GORM.
Структура проекта
-
cmd/
-
main.go
- Запуск сервера
-
-
config/
-
config.go
- Инициализация и соединение с бд
-
-
controllers/
-
todo_controller.go
- контроллер для обработки HTTP-запросов с использованием фреймворка Gin. Он включает в себя несколько функций, каждая из которых отвечает за определённый CRUD (Create, Read, Update, Delete) функционал для задач (Todo).
-
CreateTodo:
- Получает JSON-запрос и пытается его привязать к структуре
Todo
. - Валидирует структуру с использованием библиотеки
validator
. - Вызывает сервис для создания новой задачи.
- Возвращает ответ с созданной задачей или ошибкой.
- Получает JSON-запрос и пытается его привязать к структуре
-
GetTodos:
- Вызывает сервис для получения всех задач.
- Возвращает список задач или ошибку.
-
GetTodoByID:
- Получает ID задачи из параметров URL.
- Вызывает сервис для получения задачи по этому ID.
- Возвращает найденную задачу или сообщение об ошибке, если задача не найдена.
-
UpdateTodo:
- Получает ID задачи из параметров URL.
- Получает JSON-запрос и пытается его привязать к структуре
Todo
. - Валидирует структуру с использованием библиотеки
validator
. - Вызывает сервис для обновления задачи по ID.
- Возвращает обновлённую задачу или ошибку.
-
DeleteTodo:
- Получает ID задачи из параметров URL.
- Вызывает сервис для удаления задачи по этому ID.
- Возвращает сообщение об успешном удалении или ошибку, если задача не найдена.
-
user_controller.go
- контроллеры для управления пользователями с использованием фреймворка Gin
-
Register:
- Получает данные пользователя из тела запроса и преобразует их в структуру
User
. - Проверяет корректность данных (валидацию).
- Вызывает сервис для регистрации пользователя.
- Возвращает ответ с соответствующим статусом (успешная регистрация или ошибка).
- Получает данные пользователя из тела запроса и преобразует их в структуру
-
Login:
- Получает данные для входа (имя пользователя и пароль) из тела запроса.
- Вызывает сервис для аутентификации пользователя и получения токена.
- Возвращает токен или сообщение об ошибке.
-
GetUserProfile:
- Получает текущего пользователя из контекста запроса.
- Возвращает данные профиля пользователя или сообщение об ошибке, если пользователь не найден.
-
GetUsers:
- Получает всех пользователей с помощью сервиса.
- Возвращает список пользователей или сообщение об ошибке.
-
GetUserByID:
- Получает ID пользователя из параметров URL.
- Вызывает сервис для получения данных пользователя по ID.
- Возвращает данные пользователя или сообщение об ошибке, если пользователь не найден.
-
UpdateUser:
- Получает ID пользователя из параметров URL и новые данные пользователя из тела запроса.
- Проверяет корректность новых данных (валидацию).
- Вызывает сервис для обновления данных пользователя.
- Возвращает обновленные данные пользователя или сообщение об ошибке.
-
DeleteUser:
- Получает ID пользователя из параметров URL.
- Вызывает сервис для удаления пользователя по ID.
- Возвращает сообщение об успешном удалении или сообщение об ошибке, если пользователь не найден.
-
Основные компоненты:
- Gin: веб-фреймворк для маршрутизации и обработки HTTP-запросов.
- Validator: библиотека для валидации структур данных.
- Services: пакет, содержащий бизнес-логику для работы с задачами.
- Utils: пакет для вспомогательных функций, таких как формирование ответов.
-
-
database/
-
migration.go
- Основная точку входа, которая использует пакет
gorm
для работы с базой данных.
- Main:
- Инициализация базы данных:
- Получение объекта базы данных:
- Миграция таблиц:
- Основная точку входа, которая использует пакет
-
-
domain/
-
error_response.go
- Структура ErrorResponse, которая используется для представления сообщений об ошибках в формате JSON.
-
success_response.go
- Структура Response, которая используется для представления сообщений об успехах в формате JSON.
-
todo.go
- Стуруктура Todo
-
todoResponse
- Структура TodoResponse, которая используется для представлния сообщений с Todo
-
user.go
- Структура User
-
userResponse.go
- Структура UserResponse, которая используется для представлния сообщений с User
-
-
middleware/
-
auth_middleware.go
- Middleware проверяет наличие и валидность токена аутентификации в заголовке HTTP-запроса и выполняет соответствующие действия.
-
Функция
AuthMiddleware
:- Определяется функция
AuthMiddleware
, возвращающая обработчик (handler) для использования в качестве middleware.
- Определяется функция
-
Основная логика аутентификации:
-
Получение токена:
- Извлекается заголовок
Authorization
из HTTP-запроса. - Если токен отсутствует, возвращается ответ с кодом
http.StatusUnauthorized
и сообщение об ошибке, после чего обработка запроса прекращается (c.Abort()
).
- Извлекается заголовок
-
Проверка токена:
- Токен проверяется с помощью функции
utils.ValidateToken
, которая возвращает информацию о пользователе (claims
) и ошибку (err
). - Если проверка не проходит, возвращается ответ с кодом
http.StatusUnauthorized
и сообщение об ошибке, после чего обработка запроса прекращается.
- Токен проверяется с помощью функции
-
Загрузка пользователя:
- Выполняется запрос к базе данных для получения пользователя по идентификатору из токена (
claims.UserID
). - Если пользователь не найден, возвращается ответ с кодом
http.StatusUnauthorized
и сообщение об ошибке, после чего обработка запроса прекращается.
- Выполняется запрос к базе данных для получения пользователя по идентификатору из токена (
-
Установка пользователя в контекст:
- Если пользователь успешно найден, он устанавливается в контекст запроса (
c.Set("user", user)
), чтобы быть доступным в последующих обработчиках.
- Если пользователь успешно найден, он устанавливается в контекст запроса (
-
-
Продолжение обработки запроса:
- Если все проверки прошли успешно, запрос передается дальше следующему обработчику в цепочке (
c.Next()
).
- Если все проверки прошли успешно, запрос передается дальше следующему обработчику в цепочке (
-
-
repositories/
-
todo_repository.go
- функции-репозитории для работы с задачами (Todo) в базе данных, используя GORM. Репозитории инкапсулируют логику доступа к данным и обеспечивают CRUD-операции (создание, чтение, обновление, удаление).
-
CreateTodoRepository:
- Создает новую задачу в базе данных.
- Получает соединение с базой данных через
config.GetDB()
. - Использует метод
Create
для добавления новой задачи и возвращает возможную ошибку.
-
GetTodosRepository:
- Возвращает все задачи из базы данных.
- Инициализирует срез
todos
для хранения задач. - Получает соединение с базой данных и использует метод
Find
для получения всех задач. - Возвращает список задач и возможную ошибку.
-
GetTodoByIDRepository:
- Возвращает задачу по её идентификатору (ID).
- Инициализирует переменную
todo
для хранения задачи. - Получает соединение с базой данных и использует метод
First
для поиска задачи по ID. - Возвращает найденную задачу и возможную ошибку.
-
UpdateTodoRepository:
- Обновляет информацию о задаче в базе данных.
- Получает соединение с базой данных и использует метод
Save
для обновления задачи. - Возвращает возможную ошибку.
-
DeleteTodoRepository:
- Удаляет задачу из базы данных по её идентификатору (ID).
- Получает соединение с базой данных и использует метод
Delete
для удаления задачи. - Возвращает возможную ошибку.
-
user_repository.go
- функции-репозитории для работы с пользователями в базе данных, используя GORM. Репозитории обеспечивают CRUD-операции (создание, чтение, обновление, удаление) для сущности пользователя (User).
-
CreateUserRepository:
- Создает нового пользователя в базе данных.
- Получает соединение с базой данных через
config.GetDB()
. - Использует метод
Create
для добавления нового пользователя и возвращает возможную ошибку.
-
GetUsersRepository:
- Возвращает всех пользователей из базы данных.
- Инициализирует срез
users
для хранения пользователей. - Получает соединение с базой данных и использует метод
Find
для получения всех пользователей, предварительно загружая связанные задачи (Todos
). - Возвращает список пользователей и возможную ошибку.
-
GetUserByUsername:
- Возвращает пользователя по его имени (username).
- Инициализирует переменную
user
для хранения пользователя. - Получает соединение с базой данных и использует метод
Where
для поиска пользователя по имени и методFirst
для получения первого найденного результата. - Возвращает найденного пользователя и возможную ошибку.
-
GetUserByIDRepository:
- Возвращает пользователя по его идентификатору (ID).
- Инициализирует переменную
user
для хранения пользователя. - Получает соединение с базой данных и использует метод
First
для поиска пользователя по ID, предварительно загружая связанные задачи (Todos
). - Возвращает найденного пользователя и возможную ошибку.
-
UpdateUserRepository:
- Обновляет информацию о пользователе в базе данных.
- Получает соединение с базой данных и использует метод
Save
для обновления пользователя. - Возвращает возможную ошибку.
-
DeleteUserRepository:
- Удаляет пользователя из базы данных по его идентификатору (ID).
- Получает соединение с базой данных и использует метод
Delete
для удаления пользователя. - Возвращает возможную ошибку.
-
-
routes/
-
routes.go
- маршруты (routes) на основе Gin, задавая пути для операций с пользователями и задачами (Todo). Он также применяет middleware для аутентификации к определённым маршрутам.
-
Пакеты и импорт:
- Импортируются необходимые пакеты:
gin-gonic/gin
для работы с веб-фреймворком Gin, а также локальные пакетыtodolist/controllers
иtodolist/middleware
.
- Импортируются необходимые пакеты:
-
Функция
RegisterRoutes
:- Функция
RegisterRoutes
регистрирует маршруты для приложения, принимая на вход экземплярgin.Engine
.
- Функция
-
Маршруты для пользователей
-
r.POST("/register", controllers.Register)
: Маршрут для регистрации нового пользователя. -
r.POST("/login", controllers.Login)
: Маршрут для входа пользователя. -
r.GET("/users/:id", controllers.GetUserByID)
: Маршрут для получения пользователя по его ID. -
r.GET("/users", controllers.GetUsers)
: Маршрут для получения всех пользователей. -
Группа маршрутов
userRoutes
с префиксом/user
, к которой применяется middleware аутентификацииAuthMiddleware
:userRoutes.GET("/profile", controllers.GetUserProfile)
: Маршрут для получения профиля текущего пользователя.userRoutes.PATCH("/:id", controllers.UpdateUser)
: Маршрут для обновления пользователя по его ID.userRoutes.DELETE("/:id", controllers.DeleteUser)
: Маршрут для удаления пользователя по его ID.
-
-
Маршруты для задач (Todo):
- Группа маршрутов
todoRoutes
с префиксом/todos
, к которой применяется middleware аутентификацииAuthMiddleware
:todoRoutes.POST("/", controllers.CreateTodo)
: Маршрут для создания новой задачи.todoRoutes.GET("/", controllers.GetTodos)
: Маршрут для получения всех задач.todoRoutes.GET("/:id", controllers.GetTodoByID)
: Маршрут для получения задачи по её ID.todoRoutes.PATCH("/:id", controllers.UpdateTodo)
: Маршрут для обновления задачи по её ID.todoRoutes.DELETE("/:id", controllers.DeleteTodo)
: Маршрут для удаления задачи по её ID.
- Группа маршрутов
-
-
services/
-
todo_service.go
- сервисы для работы с задачами (Todo), используя репозитории для выполнения операций с базой данных. Сервисы предоставляют более высокий уровень абстракции для логики бизнес-процессов, инкапсулируя детали взаимодействия с репозиториями.
-
CreateTodoService:
- Создает новую задачу.
- Вызывает функцию репозитория
CreateTodoRepository
для добавления новой задачи в базу данных. - Возвращает возможную ошибку.
-
GetTodosService:
- Получает все задачи из базы данных.
- Вызывает функцию репозитория
GetTodosRepository
для получения всех задач. - Возвращает список задач и возможную ошибку.
-
GetTodoByIDService:
- Получает задачу по её идентификатору (ID).
- Вызывает функцию репозитория
GetTodoByIDRepository
для получения задачи по ID. - Возвращает найденную задачу и возможную ошибку.
-
UpdateTodoService:
- Обновляет информацию о задаче.
- Сначала получает существующую задачу по её ID с помощью
GetTodoByIDRepository
. - Если задача найдена, обновляет её поля (заголовок и статус выполнения) значениями из переданного объекта
todo
. - Вызывает функцию репозитория
UpdateTodoRepository
для сохранения обновлённой задачи в базе данных. - Возвращает обновлённую задачу и возможную ошибку.
-
DeleteTodoService:
- Удаляет задачу из базы данных по её идентификатору (ID).
- Вызывает функцию репозитория
DeleteTodoRepository
для удаления задачи. - Возвращает возможную ошибку.
-
user_service.go
- сервисы для работы с пользователями, используя репозитории и утилиты для выполнения операций. Сервисы предоставляют более высокий уровень абстракции для логики бизнес-процессов.
-
RegisterService:
- Регистрирует нового пользователя.
- Хэширует пароль пользователя с помощью
bcrypt
. - Обновляет пароль пользователя на хэшированный.
- Вызывает функцию репозитория
CreateUserRepository
для добавления нового пользователя в базу данных. - Возвращает возможную ошибку.
-
LoginService:
- Выполняет вход пользователя.
- Ищет пользователя по его имени с помощью
GetUserByUsername
. - Если пользователь не найден, возвращает ошибку "user not found".
- Сравнивает хэшированный пароль пользователя с введенным паролем с помощью
bcrypt.CompareHashAndPassword
. - Если пароли не совпадают, возвращает ошибку "invalid credentials".
- Генерирует токен для пользователя с помощью
utils.GenerateToken
. - Обновляет пользователя с новым токеном в базе данных с помощью
UpdateUserRepository
. - Возвращает токен и возможную ошибку.
-
GetUsersService:
- Получает всех пользователей из базы данных.
- Вызывает функцию репозитория
GetUsersRepository
для получения всех пользователей. - Возвращает список пользователей и возможную ошибку.
-
GetUserByIDService:
- Получает пользователя по его идентификатору (ID).
- Вызывает функцию репозитория
GetUserByIDRepository
для получения пользователя по ID. - Возвращает найденного пользователя и возможную ошибку.
-
UpdateUserService:
- Обновляет информацию о пользователе.
- Получает существующего пользователя по его ID с помощью
GetUserByIDRepository
. - Хэширует пароль пользователя с помощью
bcrypt
. - Обновляет поля пользователя (имя и пароль) значениями из переданного объекта
user
. - Вызывает функцию репозитория
UpdateUserRepository
для сохранения обновленного пользователя в базе данных. - Возвращает обновленного пользователя и возможную ошибку.
-
DeleteUserService:
- Удаляет пользователя из базы данных по его идентификатору (ID).
- Вызывает функцию репозитория
DeleteUserRepository
для удаления пользователя. - Возвращает возможную ошибку.
-
-
utils/
-
todo_response_utils.go
- утилитная функция для создания ответа на основе списка задач (Todo).
Функция
CreateTodoResponse
:- Принимает срез задач (
todos []domain.Todo
) в качестве входного параметра. - Создаёт пустой срез
todosModel
типа[]domain.TodoResponse
для хранения преобразованных задач. - Использует функцию
lo.ForEach
для итерации по каждой задаче в спискеtodos
. - Для каждой задачи создаёт объект
domain.TodoResponse
, копируя значения полейTitle
иCompleted
из оригинальной задачи. - Добавляет созданный объект
domain.TodoResponse
вtodosModel
. - Возвращает срез
todosModel
, содержащий преобразованные задачи.
-
token_utils.go
- утилиты для работы с JSON Web Tokens (JWT). Основные функции включают генерацию и валидацию JWT.
-
Функция GenerateToken:
- Принимает идентификатор пользователя (
userID
) в качестве параметра. - Устанавливает время истечения токена на 24 часа с текущего момента (
expirationTime
). - Создаёт объект
Claims
сUserID
иExpiresAt
. - Создаёт новый JWT с помощью метода
jwt.NewWithClaims
, используя алгоритм HMAC SHA256 (jwt.SigningMethodHS256
) и claims. - Подписывает токен с использованием
jwtKey
и возвращает подписанную строку токена или ошибку.
- Принимает идентификатор пользователя (
-
Функция ValidateToken:
- Принимает строку токена (
tokenString
) в качестве параметра. - Инициализирует объект
Claims
. - Использует метод
jwt.ParseWithClaims
для парсинга и валидации токена, передавая функцию, которая возвращает секретный ключ (jwtKey
). - Если при парсинге произошла ошибка или токен недействителен (
!token.Valid
), возвращает соответствующую ошибку. - Если токен валиден, возвращает claims и
nil
в качестве ошибки.
- Принимает строку токена (
-
user_response_utils.go
- утилитная функция для создания ответа на основе списка пользователей, включающего их задачи (Todos).
- Функция CreateUserResponse:
- Принимает срез пользователей (
users []domain.User
) в качестве входного параметра. - Инициализирует пустые срезы
usersModel
типа[]domain.UserResponse
для хранения преобразованных пользователей иtodosModel
типа[]domain.TodoResponse
для хранения преобразованных задач. - Использует функцию
lo.ForEach
для итерации по каждому пользователю в спискеusers
. - Внутри первой итерации использует ещё одну итерацию
lo.ForEach
для каждого задания (Todo) пользователя. - Для каждой задачи создаёт объект
domain.TodoResponse
, копируя значения полейTitle
иCompleted
из оригинальной задачи, и добавляет его вtodosModel
. - После итерации по задачам пользователя, создаёт объект
domain.UserResponse
, копируя значения поляUsername
из оригинального пользователя и добавляя список задачtodosModel
. - Добавляет созданный объект
domain.UserResponse
вusersModel
. - Возвращает срез
usersModel
, содержащий преобразованных пользователей и их задачи.
- Принимает срез пользователей (
-
Endpoints
Todos
- POST /todos/ - Создание нового Todo. Требуется JSON с данными Todo. Требуется токен пользователя.
- GET /todos/ - Получение списка всех Todos. Требуется токен пользователя.
- GET /todos/:id - Получение информации о конкретном Todo. Требуется токен пользователя.
- PATCH /todos/:id - Изменение Todo по идентификатору. Требуется JSON с данными Todo. Требуется токен пользователя.
- DELETE /todos/:id - Удаление Todo по идентификатору. Требуется токен пользователя.
Пример JSON для создания Todo
{
"title": "newtitle",
"completed": false,
"title": 1,
}
Пользователи
- POST /register - Регистрация нового пользователя. Требуется JSON с данными пользователя.
- POST /login - Вход пользователя. Требуется JSON с данными для входа.
- GET /user/profile - Получение данных текущего пользователя. Требуется токен пользователя.
- GET /users - Получение списка всех пользователей.
- GET /users/:id - Получение пользователя.
- PATCH /user/:id - Редактирование имени и/или пароля пользователя. Требуется JSON с новым именем и/или паролем. Требуется токен пользователя.
- DELETE /user/:id - Удаление пользователя. Требуется JSON с суммой. Требуется токен пользователя.
Запуск сервера
- При запуске впервый раз:
go run database/migration.go
- Затем можно запускать контейнер вместе с БД Postgresql командой:
docker-compose up -d
- Затем запуск самого сервера
go run cmd/main.go