Options are passed as a parameter of the UseNpgsqlRest
extension:
var app = builder.Build();
app.UseNpgsqlRest(new NpgsqlRestOptions());
app.Run();
The full list of available options in the latest version is below.
This is the group of options used for authentication:
- Type:
string?
- Default:
null
Authentication type used with the Login endpoints to set the authentication type for the new ClaimsIdentity
created by the login.
This value must be set to non-null when using login endpoints, otherwise, the following error will raise: SignInAsync when principal.Identity.IsAuthenticated is false is not allowed when AuthenticationOptions.RequireAuthenticatedSignIn is true.
If the value is not set and the login endpoint is present, it will automatically get the database name from the connection string.
- Type:
string?
- Default:
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
Claim type value used to retrieve the user name.
The user name is exposed as the default name with the Name
property on the user identity by searching claims collection with this claim type.
The default is the Active Directory Federation Services Claim Type Name property with value http://schemas.microsoft.com/ws/2008/06/identity/claims/name
- Type:
string?
- Default:
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"
Claim type value used to retrieve the roles collection for the roles-based security.
The role key is used in the bool IsInRole(string role)
method to search claims to determine does the current user identity belongs to roles.
The default is the Active Directory Federation Services Claim Type Role property with value http://schemas.microsoft.com/ws/2008/06/identity/claims/role
- Type:
string?
- Default:
"scheme"
The default column name in the data reader will be used to read the value of the authentication scheme of the login process.
The textual value of this field will set the authentication scheme name for the sign-in operation.
This is useful when using multiple authentication schemes. Returning any value from the logout routine will cause a logout from only that scheme. So for example, if you have the Cookie scheme and the Bearer Token scheme configured, you can handle them separately for login and logout.
The default is "scheme"
.
- Type:
string?
- Default:
"status"
The default column name in the data reader will be used to read the value to determine the success or failure of the login operation.
This column can only be a boolean or numeric type. If it is neither boolean nor numeric, the endpoint will return status 500 InternalServerError
and you'll have to check logs.
When this field is boolean, and it is true, the login process will continue with security claims set by other fields (which usually ends up in 200 OK
if authentication is configured). If it is false, the endpoint will return 404 NotFound
and the login attempt will not continue.
When this field is numeric, and it is 200, the login process will continue with security claims set by other fields (which usually ends up in 200 OK
if authentication is configured). If it is not 200, the endpoint will return the status code the same as the value of this field, and the login attempt will not continue.
- Type:
string?
- Default:
"message"
This is the textual message that is returned in the response body.
Note: this message is only returned in a case when the configured authentication scheme doesn't write anything into the response body on a sign-in operation.
For example, the Cookie authentication scheme doesn't write anything into the body and this message is safely written to the response body. On the other hand, the Bearer Token schemes will always write the response body and this message will not be written to the response body.
- Type:
bool
- Default:
true
By default, if the column name interpreted as the security claim type, matches one of the Active Directory Federation Services Claim Types names, it will use that AD Federation Services Claim Type URI. The table can be seen here: ClaimTypes Class.
That means that if the column name is either of these NameIdentifier
- or the nameidentifier
(case is ignored), or the name_identifier
(for the camel case converted names, which is the default), the actual security claim type is http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
according to this table.
If the name is not found in this table, security is the column name as-is but parsed by the default name converter.
In this example column name name_identifier
will be the security claim type the nameIdentifier
.
This behavior that uses the AD Federation Services Claim Type can be turned off with this option.
- Type:
ulong
- Default:
25
The number of rows to buffer in the string builder before sending the response. The default is 25. This applies to rows in JSON object array when returning records from the database.
Set to 0 to disable buffering and write a response for each row.
Set to 1 to buffer the entire array (all rows).
Notes:
- Disabling buffering can have a slight negative impact on performance since buffering is far less expensive than writing to the response stream.
- Setting higher values can have a negative impact on memory usage, especially when returning large datasets.
- Type:
string?
- Default:
null
The connection string to the database. This is the optional value if the ConnectionFromServiceProvider
option is set to true.
Note: the connection string must run as a super user or have select permissions on information_schema
and pg_catalog
system tables. If the ConnectionFromServiceProvider
option is set to false and ConnectionString
is null, the middleware will raise an ArgumentException
error.
- Type:
Dictionary<string, StringValues>
- Default:
[]
Custom request headers dictionary that will be added to NpgsqlRest requests.
Note: these values are added to the request headers dictionary before they are sent as a context or parameter to the PostgreSQL routine and as such not visible to the browser debugger.
- Type:
string?
- Default:
null
Filter schema names by using a SIMILAR TO
operator with this value, or set it to null to ignore this parameter.
- Type:
string?
- Default:
null
Filter schema names by using a NOT SIMILAR TO
operator with this value, or set it to null to ignore this parameter.
- Type:
string[]?
- Default:
null
List of schema names to be included or null to ignore this parameter.
- Type:
string[]?
- Default:
null
List of schema names to be excluded or null to ignore this parameter.
- Type:
string?
- Default:
null
Filter names by using a SIMILAR TO
operator with this value, or set it to null to ignore this parameter.
Names are PostgreSQL object names like function or table, depending on the source.
- Type:
string?
- Default:
null
Filter names by using a NOT SIMILAR TO
operator with this value, or set it to null to ignore this parameter.
Names are PostgreSQL object names like function or table, depending on the source.
- Type:
string[]?
- Default:
null
List of names to be included or null to ignore this parameter. Names are PostgreSQL object names like function or table, depending on the source.
- Type:
string[]?
- Default:
null
List of names to be excluded or null to ignore this parameter. Names are PostgreSQL object names like function or table, depending on the source.
- Type:
string?
- Default:
"/api"
The URL prefix string for every URL created by the default URL builder or null to ignore the URL prefix.
- Type:
Func<Routine, NpgsqlRestOptions, string>
- Default:
DefaultUrlBuilder.CreateUrl
Custom function delegate that receives routine and options parameters and returns constructed URL path string for routine. Default the default URL builder that transforms snake case names to kebab case names.
Example:
app.UseNpgsqlRest(new NpgsqlRestOptions
{
//
// URL path is equal to the routine name without schema name
//
UrlPathBuilder = (routine, options) => routine.Name
});
- Type:
bool
- Default:
false
Use the NpgsqlConnection
database connection from the service provider.
If this option is true, middleware will attempt to require NpgsqlConnection
from the services collection, which means it needs to be configured. This option provides an opportunity to implement custom database connection creation. If it is false, a new NpgsqlConnection
will be created using the ConnectionString
property.
If this option is false and ConnectionString
is null
, the middleware will raise an ArgumentException
error.
- Type:
Func<NpgsqlRest.Routine, NpgsqlRest.RoutineEndpoint, NpgsqlRest.RoutineEndpoint?>?
- Default:
null
A callback function that, if defined, is executed just after the new endpoint is created. Receives routine into and new endpoint info as parameters and it is expected to return the same endpoint or null.
It offers an opportunity to modify the endpoint based on custom logic or disable endpoints by returning null based on some custom logic.
Examples:
app.UseNpgsqlRest(new NpgsqlRestOptions
{
// always skip public routines
EndpointCreated = (routine, endpoint) => routine.Schema == "public" ? null : endpoint
});
app.UseNpgsqlRest(new NpgsqlRestOptions
{
// force all endpoints to have POST method
EndpointCreated = (routine, endpoint) =>
{
endpoint.Method = Method.POST;
return endpoint;
}
});
app.UseNpgsqlRest(new NpgsqlRestOptions
{
// All public schema always require authorization
EndpointCreated = (routine, endpoint) =>
{
if (routine.Schema == "public")
{
endpoint.RequiresAuthorization = true;
}
return endpoint;
}
});
- Type:
Func<string?, string?>
- Default:
NpgsqlRest.Defaults.DefaultNameConverter.ConvertToCamelCase
Custom function callback that receives names from PostgreSQL (parameter names, column names, etc), and is expected to return the same or new name. It offers an opportunity to convert names based on certain conventions. The default converter converts snake case names into camel case names.
Example:
app.UseNpgsqlRest(new NpgsqlRestOptions
{
//
// Use the original name for parameters and JSON field names
//
NameConverter = name => name
});
- Type:
bool
- Default:
false
When set to true, it will force all created endpoints to require authorization.
Authorization requirements for individual endpoints can be changed with the EndpointCreated
function callback, or by using comment annotations.
- Type:
Microsoft.Extensions.Logging.ILogger?
- Default:
null
Set this option to provide a custom logger implementation. The default null value will cause middleware to create a default logger named NpgsqlRest
from the default logger factory in the service collection.
Example:
app.UseNpgsqlRest(new NpgsqlRestOptions
{
// use empty logger
Logger = new EmptyLogger()
});
public class EmptyLogger : ILogger
{
public IDisposable BeginScope<TState>(TState state) => throw new NotImplementedException();
public bool IsEnabled(LogLevel logLevel) => false;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) { }
}
- Type:
string?
- Default:
null
Change the logger name with this option.
- Type:
bool
- Default:
true
When this value is true, all changes in the endpoint properties that are set from the comment annotations will be logged as information:
info: NpgsqlRest[0]
Function auth.get_user_details has set REQUIRED AUTHORIZATION by the comment annotation.
- Type:
bool
- Default:
true
When this value is true, all created endpoint events will be logged as information with method and path. Set to false to disable logging this information.
Example log entry with default Microsoft logger:
info: NpgsqlRest[0]
Created endpoint POST /api/hello-world
- Type:
bool
- Default:
true
When this value is true, all connection events are logged (depending on the level). This is usually triggered by the PostgreSQL RAISE
statements. Set to false to disable logging these events.
Example function with RAISE statement:
create function return_text(_t text)
returns text
language plpgsql
as
$$
begin
raise info '_t = %', _t;
return _t;
end;
$$;
Execution for parameter value "ABC" will produce the following log:
info: NpgsqlRest[0]
PL/pgSQL function return_text(text) line 3 at RAISE:
_t = ABC
- Type:
bool
- Default:
false
Set this option to true to log information for every executed command and query (including parameters and parameter values).
When this option is true, the following log will be produced:
info: NpgsqlRest[0] -- POST http://localhost:5000/api/return-text
select public.return_text($1)
- Type:
bool
- Default:
false
Set this option to true to include parameter values when logging commands. This only applies when LogCommands
is true.
Execution for parameter value "ABC" will produce the following log:
info: NpgsqlRest[0] -- POST http://localhost:5000/api/return-text
-- $1 text = 'ABC'
select public.return_text($1)
- Type:
int?
- Default:
null
Sets the wait time (in seconds) on database commands, before terminating the attempt to execute a command and generating an error. This value when it is not null will override the NpgsqlCommand
which is 30 seconds.
Command timeout property for individual endpoints can be changed with the EndpointCreated
function callback, or by using comment annotations.
- Type:
Method?
- Default:
null
When not null, force a method type for all created endpoints. Method types are GET
, PUT
, POST
, DELETE
, HEAD
, OPTIONS
, TRACE
, PATCH
or CONNECT
. When this value is null (default), default logic will apply to determine individual endpoint methods, depending on the routine source.
For example:
- For function and procedures, routines with volatility option
VOLATILE
are alwaysPOST
, unless the name starts with,get_
, contains_get_
or ends with_get
, the the method isGET
. If the volatility option is notVOLATILE
, method is alwaysGET
. - For tables and views, the method depends on the type of CRUD operation. Create is
PUT
. Read isGET
. The update isPOST
. And, delete isDELETE
.
This option for individual endpoints can be changed with the EndpointCreated
function callback, or by using comment annotations.
- Type:
RequestParamType?
- Default:
null
When not null, set the request parameter position (request parameter types) for all created endpoints. Values are:
QueryString
: parameters are sent using the query string.BodyJson
: parameters are sent using JSON request body.
When this value is null (default), the request parameter type is QueryString
for all GET
and DELETE
endpoints, otherwise, the request parameter type is BodyJson
.
This option for individual endpoints can be changed with the EndpointCreated
function callback, or by using comment annotations.
- Type:
Action<ParameterValidationValues>?
- Default:
null
Custom parameter validation method. When this callback option is not null, it will be executed for every database parameter created.
The input structure will contain a current HTTP context that offers the opportunity to alter the response and cancel the request: If the current HTTP response reference has started or the status code is different than 200 OK, command execution will be canceled and the response will be returned.
Example:
static void Validate(ParameterValidationValues p)
{
if (p.Routine.Name == "my_function" && p.Parameter.Value?.ToString() == "XXX")
{
p.Context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
}
}
app.UseNpgsqlRest(new NpgsqlRestOptions
{
ValidateParameters = Validate
});
- Type:
Func<ParameterValidationValues, Task>?
- Default:
null
Custom parameter validation method, the asynchronous version. When this callback option is not null, it will be executed for every database parameter created.
The input structure will contain a current HTTP context that offers the opportunity to alter the response and cancel the request: If the current HTTP response reference has started or the status code is different than 200 OK, command execution will be canceled and the response will be returned.
Example:
static async Task ValidateAsync(ParameterValidationValues p)
{
if (p.Routine.Name == "my_function" && p.Parameter.Value?.ToString() == "XXX")
{
p.Context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
await p.Context.Response.WriteAsync($"Paramater {p.ParamName} is not valid.");
}
}
app.UseNpgsqlRest(new NpgsqlRestOptions
{
ValidateParametersAsync = ValidateAsync
});
- Type:
CommentsMode
- Default:
OnlyWithHttpTag
Configure how the comment annotations will behave:
Ignore
will create all endpoints and ignore comment annotations.ParseAll
(default) will create all endpoints and parse comment annotations to alter the endpoint.OnlyWithHttpTag
will only create endpoints that contain theHTTP
tag in the comments and then parse comment annotations.
- Type:
RequestHeadersMode
- Default:
Ignore
Configure how to send request headers to PostgreSQL routines execution:
Ignore
: (default) Don't send any request headers to routines.Context
: sets a context variable for the current sessioncontext.headers
containing JSON string with current request headers. This executesset_config('context.headers', headers, false)
before any routine executions.Parameter
: sends request headers to the routine parameter defined with theRequestHeadersParameterName
option. A parameter with this name must exist, must be one of the JSON or text types and must have the default value defined. This option for individual endpoints can be changed with theEndpointCreated
function callback, or by using comment annotations.
- Type:
string
- Default:
"headers"
Sets a parameter name that will receive a request headers JSON when the Parameter
value is used in RequestHeadersMode
options.
A parameter with this name must exist, must be one of the JSON or text types and must have the default value defined.
This option for individual endpoints can be changed with the EndpointCreated
function callback, or by using comment annotations.
- Type:
Action<(Routine routine, RoutineEndpoint endpoint)[]>?
- Default:
null
Callback, if defined, will be executed after all endpoints are created. It receives an array of routine info and endpoint info tuples (Routine routine, RoutineEndpoint endpoint)
. Used mostly for code generation.
Example:
static void WriteFile(Routine routine, RoutineEndpoint endpoint)
{
// write file here
}
app.UseNpgsqlRest(new NpgsqlRestOptions
{
EndpointsCreated = endpoints =>
{
foreach(var (routine, endpoint) in endpoints)
{
WriteFile(routine, endpoint);
}
}
});
- Type:
Func<(Routine routine, NpgsqlCommand command, HttpContext context), Task>?
- Default:
null
Asynchronous callback function that, if defined, will be called after every database command is created and before it has been executed.
It receives a tuple parameter with routine info, a newly created command and the current HTTP context. Command instance and HTTP context offer the opportunity to execute the command and return a completely different, custom response format.
If the current HTTP context is modified in any shape or form, it will be returned immediately, otherwise, it will fall back to a default behavior.
Example of returning a custom format in CSV rather than JSON:
static async Task CommandCallbackAsync((Routine routine, NpgsqlCommand command, HttpContext context) p)
{
if (p.routine.Name == "get_csv_data")
{
p.context.Response.ContentType = "text/csv";
await using var reader = await p.command.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
await p
.context
.Response
.WriteAsync($"{reader[0]},{reader[1]},{reader.GetDateTime(2):s},{reader.GetBoolean(3).ToString().ToLowerInvariant()}\n");
}
}
}
app.UseNpgsqlRest(new NpgsqlRestOptions
{
CommandCallbackAsync = CommandCallbackAsync
});
- Type:
IEnumerable<IEndpointCreateHandler>
- Default:
[]
List of IEndpointCreateHandler
type handlers executed sequentially after endpoints are created. Used to add the different code generation plugins.
Example:
app.UseNpgsqlRest(new NpgsqlRestOptions
{
// create HTTP file and the Typescript Client from plugins
EndpointCreateHandlers = [
new HttpFile(),
new TsClient("../Frontend/src/api.ts")]
});
- Type:
Action<List<IRoutineSource>>
- Default:
source => {}
Action callback that, if defined, is executed after routine sources are created and before they are processed into endpoints.
Receives a parameter with the list of IRoutineSource
instances. This list will always contain a single item - functions and procedures source. Use this callback to modify the routine source list and add new sources from plugins.
Example:
app.UseNpgsqlRest(new NpgsqlRestOptions
{
// add tables and views CRUD source from plugin
SourcesCreated = sources => sources.Add(new CrudSource())
});
- Type:
TextResponseNullHandling
- Default:
EmptyString
Sets the default behavior of plain text responses when the execution returns the NULL
value from the database:
EmptyString
(default) returns an empty string response with status code 200 OK.NullLiteral
returns a string literalNULL
with the status code 200 OK.NoContent
returns status code 204 NO CONTENT.
This option for individual endpoints can be changed with the EndpointCreated
function callback, or by using comment annotations.
- Type:
QueryStringNullHandling
- Default:
Ignore
Sets the default behavior on how to pass the NULL
values with query strings:
EmptyString
empty string values are interpreted asNULL
values. This limits sending empty strings via query strings.NullLiteral
literal string valuesNULL
(case insensitive) are interpreted asNULL
values.Ignore
(default)NULL
values are ignored, query string receives only empty strings.
This option for individual endpoints can be changed with the EndpointCreated
function callback, or by using comment annotations.
-
Type:
bool
-
Default:
true
-
Set to true to return message property on exception from the
NpgsqlException
object on response body. The default is true.
- Type:
Dictionary<string, int>
- Default:
{ { "57014", 205 } }
Dictionary setting that maps the PostgreSQL Error Codes (see the errcodes-appendix to HTTP Status Codes.
Default is { "57014", 205 }
which maps PostgreSQL query_canceled
error to HTTP 205 Reset Content
. If the mapping doesn't exist, the standard HTTP 500 Internal Server Error
is returned.
- Type:
Action<NpgsqlConnection, Routine, RoutineEndpoint, HttpContext>?
- Default:
null
Callback option: Action<NpgsqlConnection, Routine, RoutineEndpoint, HttpContext>? BeforeConnectionOpen
.
This is used to set the application name parameter (for example) without having to use the service provider. It executes before the new connection is open for the request. For example:
app.UseNpgsqlRest(new()
{
ConnectionString = connectionString,
BeforeConnectionOpen = (NpgsqlConnection connection, Routine routine, RoutineEndpoint endpoint, HttpContext context) =>
{
var username = context.User.Identity?.Name;
connection.ConnectionString = new NpgsqlConnectionStringBuilder(connectionString)
{
ApplicationName = string.Concat(
"{\"app\":\"",
builder.Environment.ApplicationName,
username is null ? "\",\"user\":null}" : string.Concat("\",\"user\":\"", username, "\"}"))
}.ConnectionString;
}
}