We have these tables:
users (id, user_name)
user_stats (user_id, rating, matches_count, etc.)
We want to make a subscription to the current user (with some relations, like user_stats) with this query:
SELECT *
FROM users
WHERE id = X-Hasura-User-Id
So, we have two ways to do that:
X-Hasura-User-Id session variable.Pros:
users)Cons:
So we can't use this way due to performance reasons.
{"id":{"_eq":"X-Hasura-User-Id"}})Pros:
Cons:
users_current instead of users), so we can't reuse cache and the same fragments on our react/apollo frontend. What we can do?
@Maxpain177 Any reason you aren't setting the {"id":{"_eq":"X-Hasura-User-Id"}} check as a permission rule and then using subscriptions on the users table directly?
@0x777 any insights on the subscriptions bit?
@rikinsk Because we want to get not only current user from users table
Can you get the user id from your auth server, and query users using that and 2 different subscriptions / queries?
subscription currentUser {
currentUser:user(where: {id: {_eq: 1}}) {
id
email
}
}
subscription otherUsers {
otherUsers:user(where: {id: {_neq: 1}}) {
id
email
}
}
I agree with @kelly-ry4n: why not just look up the current user鈥檚 id and create a subscription on users filtered by that id?
@Maxpain177
Both the solutions you suggested work (with small changes)
Subscriptions on functions which accept session variables as their arguments are multiplexed. The function should look something like this:
create function get_current_user(hasura_session json) returns setof users as $$
select * from users where id = (hasura_session ->> 'x-hasura-user-id')::Int
$$ language sql stable;
Console doesn't yet support tracking functions which require session variables so you'll need to manually hit /v1/query endpoint with this query:
{
"type": "track_function",
"version": 2,
"args": {
"function": {
"schema": "public",
"name": "get_current_user"
},
"configuration": {
"session_argument": "hasura_session"
}
}
}
or it can also be made part of metadata as follows:
{
"version": 2,
"tables": [
{
"table": {
"schema": "public",
"name": "users"
}
}
],
"functions": [
{
"function": {
"schema": "public",
"name": "get_current_user"
},
"configuration": {
"session_argument": "hasura_session"
}
}
]
}
To avoid the cons that you listed, you just need to create an object relationship to the users table. So this will be the workflow:
current_user as follows:Create permission on current_user for user roles as {"user_id": {"_eq": "x-hasura-user-id"}}
Create a manual object relationship from current_user view to user table so that you can access all the relationships defined on the user table. Your subscription would look something like this:
```graphql
subscription current_user {
current_user {
user {
id
stats {
}
}
}
}
You can use any of the above approaches.
Most helpful comment
@Maxpain177
Both the solutions you suggested work (with small changes)
Using functions:
Subscriptions on functions which accept session variables as their arguments are multiplexed. The function should look something like this:
Console doesn't yet support tracking functions which require session variables so you'll need to manually hit
/v1/queryendpoint with this query:or it can also be made part of metadata as follows:
Using views
To avoid the cons that you listed, you just need to create an object relationship to the users table. So this will be the workflow:
current_useras follows:```sql
create view current_user as select * from users
````
Create permission on
current_userforuserroles as{"user_id": {"_eq": "x-hasura-user-id"}}Create a manual object relationship from
current_userview tousertable so that you can access all the relationships defined on the user table. Your subscription would look something like this:```graphql
subscription current_user {
current_user {
user {
id
stats {
}
}
}
You can use any of the above approaches.