Parameter queries allow parameters to be defined on a bucket to group data. These queries can use parameters from the JWT (we loosely refer to these as token parameters), such as a user_id, or parameters from clients directly.
Copy
bucket_definitions: # Bucket Name user_lists: # Parameter Query parameters: SELECT request.user_id() as user_id # Data Query data: - SELECT * FROM lists WHERE lists.owner_id = bucket.user_id user_lists_table: # Similar query, but using a table # Access can instantly be revoked by deleting the user row/document parameters: SELECT id as user_id FROM users WHERE users.id = request.user_id() data: - SELECT * FROM lists WHERE lists.user_id = bucket.user_id
Available functions in sync rules are:
request.user_id(): Returns the JWT subject, same as request.jwt() ->> 'sub'
request.jwt(): Returns the entire (signed) JWT payload as a JSON string.
request.user_id()request.jwt() ->> 'sub' -- Same as `request.user_id()request.parameters() ->> 'param' -- Client parameters-- Some Supabase-specific examples below. These can be used with standard Supabase tokens,-- for use cases which previously required custom tokensrequest.jwt() ->> 'role' -- 'authenticated' or 'anonymous'request.jwt() ->> 'email' -- automatic email fieldrequest.jwt() ->> 'app_metadata.custom_field' -- custom field added by a service account (authenticated)
A previous syntax for parameter queries used token_parameters. Expand the below for details on how to migrate to the recommended syntax above.
The previous syntax for parameter queries used token_parameters.user_id to return the JWT subject. Example:
Copy
bucket_definitions: by_user_parameter: parameters: SELECT token_parameters.user_id as user_id data: - SELECT * FROM lists WHERE lists.owner_id = bucket.user_id
request.user_id(): Returns the token subject, same as request.jwt() ->> 'sub' and also the same as token_parameters.user_id in the previous syntax.
The major difference from the previous token_parameters is that all payloads are preserved as-is, which can make usage a little more intuitive. This also includes JWT payload fields that were not previously accessible.
Migrating to the new syntax:
token_parameters.user_id references can simply be updated to request.user_id()
Custom parameters can be updated from token_parameters.my_custom_field to request.jwt() ->> 'parameters.my_custom_field'
This example applies if you keep your existing custom JWT as is.
bucket_definitions: by_user_parameter: # request.user_id() is the same as the previous token_parameter.user_id parameters: SELECT request.user_id() as user_id data: - SELECT * FROM lists WHERE lists.owner_id = bucket.user_id
bucket_definitions: admin_users: parameters: | SELECT id as user_id FROM users WHERE users.id = request.user_id() AND users.is_admin = true data: - SELECT * FROM lists WHERE lists.owner_id = bucket.user_id
bucket_definitions: primary_list: parameters: | SELECT primary_list_id FROM users WHERE users.id = request.user_id() data: - SELECT * FROM todos WHERE todos.list_id = bucket.primary_list_id
bucket_definitions: owned_lists: parameters: | SELECT id as list_id FROM lists WHERE owner_id = request.user_id() data: - SELECT * FROM lists WHERE lists.id = bucket.list_id - SELECT * FROM todos WHERE todos.list_id = bucket.list_id
In this example, a single query can return multiple sets of bucket parameters for a single user.
Keep in mind that the total number of buckets per user should remain limited (< 1,000), so don’t make buckets too granular.
Copy
bucket_definitions: user_lists: parameters: | SELECT list_id FROM user_lists WHERE user_lists.user_id = request.user_id() data: - SELECT * FROM lists WHERE lists.id = bucket.list_id - SELECT * FROM todos WHERE todos.list_id = bucket.list_id
Parameter queries may return multiple bucket parameters.
Note that every bucket parameter must be used in every data query.
Copy
bucket_definitions: owned_org_lists: parameters: | SELECT id as list_id, org_id FROM lists WHERE owner_id = request.user_id() data: - SELECT * FROM lists WHERE lists.id = bucket.list_id and lists.org_id = bucket.org_id - SELECT * FROM todos WHERE todos.list_id = bucket.list_id and todos.org_id = bucket.org_id
Multiple parameter queries can be used in the same bucket definition.
It is important in this case that the output columns are exactly the same for each query in the bucket definition, as these define the bucket parameters.
Copy
bucket_definitions: user_lists: parameters: - SELECT id as list_id FROM lists WHERE owner_id = request.user_id() - SELECT list_id FROM user_lists WHERE user_lists.user_id = request.user_id() data: - SELECT * FROM lists WHERE lists.id = bucket.list_id - SELECT * FROM todos WHERE todos.list_id = bucket.list_id
Keep in mind that the total number of buckets per user should remain limited (< 1,000), so don’t make buckets too granular.
Parameter queries are not run directly on a database. Instead, the queries are used to pre-process rows/documents as they are replicated, and index them for efficient use in the sync process.
The supported SQL is based on a small subset of the SQL standard syntax.
Notable features and restrictions:
Only simple SELECT statements are supported.
No JOIN, GROUP BY or other aggregation, ORDER BY, LIMIT, or subqueries are supported.
For token parameters, only = operators are supported, and IN to a limited extent.