Я пытаюсь встроить систему авторизации RBAC в приложение. Пользователи, роли и разрешения хранятся в базе данных. Каждая роль может быть назначена каждому пользователю. Вот почему у меня есть таблицы user_account
и role
, склеенные во взаимосвязь «многие ко многим» с помощью соединительной таблицы user_role
. Урезанный, настройка базы данных выглядит следующим образом:
CREATE TABLE user_account (
id uuid NOT NULL DEFAULT uuid_generate_v1mc(),
email character varying(128) NOT NULL,
CONSTRAINT user_account_pkey PRIMARY KEY (id),
CONSTRAINT user_account_email_key UNIQUE (email)
);
CREATE TABLE role (
id uuid NOT NULL DEFAULT uuid_generate_v1mc(),
name character varying(128) NOT NULL,
CONSTRAINT role_pkey PRIMARY KEY (id),
CONSTRAINT role_name_key UNIQUE (name)
);
CREATE TABLE user_role (
user_id uuid NOT NULL,
role_id uuid NOT NULL,
CONSTRAINT user_role_pkey PRIMARY KEY (user_id, role_id),
CONSTRAINT user_role_fkey_user FOREIGN KEY (user_id) REFERENCES user_account (id) ON DELETE CASCADE,
CONSTRAINT user_role_fkey_role FOREIGN KEY (role_id) REFERENCES role (id) ON DELETE CASCADE
);
Очевидно, я настроил соответствующие структуры го:
type User struct {
ID string `db:"id"`
Email string `db:"email"`
}
type Role struct {
ID string `db:"id"`
Name string `db:"name"`
}
Пока все хорошо. Извлечение одной или нескольких строк по отдельности в соответствующую структуру go не является проблемой. Но я бы предпочел получить пользователя и все назначенные ему роли. Полученная структура go будет выглядеть примерно так:
type User struct {
ID string `db:"id"`
Email string `db:"email"`
Roles []Role
}
Что я спрашиваю: какова лучшая стратегия для извлечения данных в структуру?
- Извлечение пользовательской записи с помощью запроса, выборка всех назначенных ему ролей другим запросом и построение структуры
User
.
или
- Получить запись пользователя и все назначенные ему роли одним запросом.
Я знаю, как сделать первый случай, но бороться со вторым. Я использую sqlx
и PostgreSQL. Возможно ли даже то, чего я пытаюсь достичь? Если да, то как? Какой тег db
использовать?
Мой наивный запрос для второго подхода выглядит следующим образом, но, очевидно, не работает должным образом:
SELECT user_account.id, user_account.email, role.id, role.name
FROM user_account
LEFT OUTER JOIN user_role
ON user_account.id = user_role.user_id
LEFT OUTER JOIN role
ON user_role.role_id = role.id
Есть предложения?