Skip to content
Written with Claude
IMPORTANT

As you may notice, this page and pretty much the entire website were obviously created with the help of AI. I wonder how you could tell? Was it a big "Written With Claude" badge on every page? I moved it to the top now (with the help of AI of course) to make it even more obvious. There are a few blogposts that were written by me manually, the old-fashioned way, I hope there will be more in the future, and those have a similar "Human Written" badge. This project (not the website), on the other hand, is a very, very different story. It took me more than two years of painstaking and unpaid work in my own free time. A story that, hopefully, I will tell someday. But meanwhile, what would you like me to do? To create a complex documentation website with a bunch of highly technical articles with the help of AI and fake it, to give you an illusion that I also did that manually? Like the half of itnernet is doing at this point? How does that makes any sense? Is that even fair to you? Or maybe to create this website manually, the old-fashioned way, just for you? While working a paid job for a salary, most of you wouldn't even get up in the morning. Would you like me to sing you a song while we're at it? For your personal entertainment? Seriously, get a grip. Do you find this information less valuable because of the way this website was created? I give my best to fix it to keep the information as accurate as possible, and I think it is very accurate at this point. If you find some mistakes, inaccurancies or problems, there is a comment section at the bottom of every page, which I also made with the help of the AI. And I woould very much appreciate if you leave your feedback there. Look, I'm just a guy who likes SQL, that's all. If you don't approve of how this website was constructed and the use of AI tools, I suggest closing this page and never wever coming back. And good riddance. And I would ban your access if I could know how. Thank you for your attention to this matter.

USER_PARAMETERS

Also known as

user_params (with or without @ prefix)

Enable passing user claims as function parameters for the endpoint.

Syntax

@user_parameters
@user_params

Examples

Basic User Parameters

sql
create function get_user_params(
    _user_id text,
    _user_name text,
    _user_roles text[]
)
returns table (
    user_id int,
    user_name text,
    user_roles text[]
)
language sql as $$
select
    _user_id::int,
    _user_name,
    _user_roles
$$;

comment on function get_user_params(text, text, text[]) is '
@authorize
@user_params
';

With Default Values (for unauthenticated access)

sql
create function get_user_params_optional(
    _user_id text = null,
    _user_name text = 'anonymous',
    _user_roles text[] = array[]::text[]
)
returns table (
    user_id int,
    user_name text,
    user_roles text[]
)
language sql as $$
select
    _user_id::int,
    _user_name,
    _user_roles
$$;

comment on function get_user_params_optional(text, text, text[]) is '
@user_params
';

Access All Claims as JSON

sql
create function get_user_ip_and_full_claims(
    _ip_address text,
    _user_claims json
)
returns table (
    ip_address text,
    user_claims json
)
language sql as $$
select
    _ip_address,
    _user_claims
$$;

comment on function get_user_ip_and_full_claims(text, json) is '
@authorize
@user_params
';

Combined with User Context

sql
comment on function user_profile() is
'HTTP GET
@authorize
@user_context
@user_parameters';

Behavior

  • Automatically injects user claim values into matching function parameters before execution
  • Parameters are matched by name according to ParameterNameClaimsMapping configuration
  • Default behavior for all endpoints can be configured via UseUserParameters
  • Parameters with default values work without authentication; claim values override defaults when authenticated
  • Parameters not found in claims use their default values or null
  • Claim values are always passed as text type. For multi-value claims (like roles), values are passed as text[]. PostgreSQL handles type coercion to your parameter types.

Default Parameter Mapping

Parameter NameClaimDescription
_user_iduser_idUser identifier
_user_nameuser_nameUsername
_user_rolesuser_rolesUser roles (array)
_ip_address-Client IP address
_user_claims-All claims serialized as JSON

Differences from USER_CONTEXT

FeatureUSER_PARAMETERSUSER_CONTEXT
Access methodFunction parameterscurrent_setting()
Works without authYes (with defaults)Yes (returns empty)
Type safetyPostgreSQL enforcedManual casting required
PerformanceSlightly fasterSlightly slower
  • USER_CONTEXT - Access user claims via PostgreSQL session context variables
  • AUTHORIZE - Require authentication

Comments

Released under the MIT License.