Skip to content
This page View Markdown Open in ChatGPT Open in Claude

Multi tenant instance updated

Call it when the connection string of a tenant of a multi-tenant instance changes in the tenants table : every server drops the connection pools of that tenant and the cached answers of the instance and of the tenants table, so the next request of the tenant reads its row again and connects to the new database.

Method POST
URL /api/system-api/admin/multi-tenant-instance-updated : admin is the user path of your account
Body { instanceName, username } or an array of them
Answer data : one answer per item, { success, data }
From code g.sys.system.multiTenantInstanceUpdated

The call

Body : one tenant of one instance
{ "instanceName": "crm", "username": "acme" }
Body : several
[ { "instanceName": "crm", "username": "acme" }, { "instanceName": "billing", "username": "acme" } ]
Answer
{
    "success": true,
    "statusCode": 200,
    "data": [
        { "success": true, "data": true },
        { "success": false, "data": false, "error": { "code": 400, "message": "Instance 'billing' is not a multi tenant structure instance." } }
    ]
}
  • Each item is answered on its own : an unknown instance (404) or an instance which is not multi-tenant (400) does not stop the other items.
  • Both fields are required.
  • Until this API is called, the servers keep using the pools they have. For PostgreSQL, the pools of every database of the tenant are dropped.

From code

await g.sys.system.multiTenantInstanceUpdated({ instanceName: 'crm', username: 'acme' });
await g.sys.system.multi_tenant_instance_updated('crm', 'acme')
$g->sys->system->multiTenantInstanceUpdated('crm', 'acme');
await g.Sys.System.MultiTenantInstanceUpdated(new MultiTenantInstanceUpdated("crm", "acme"));
if _, err := g.Sys.System.MultiTenantInstanceUpdated(am.MultiTenantInstanceUpdated{InstanceName: "crm", Username: "acme"}); err != nil {
    return nil, err
}
g.sys.system.multi_tenant_instance_updated(MultiTenantInstanceUpdated::new("crm", "acme"))?;
g.sys.system.multiTenantInstanceUpdated(new MultiTenantInstanceUpdated("crm", "acme"));
g.sys.system.multiTenantInstanceUpdated(MultiTenantInstanceUpdated("crm", "acme"))

Several instances at once

Several instances or tenants at once, each item answered on its own:

1
2
3
4
5
const output = await g.sys.system.multiTenantInstanceUpdated([
    { instanceName: 'crm', username: 'acme' },
    { instanceName: 'billing', username: 'acme' },
]);
// [{ success: true, data: true }, { success: false, data: false, error: { code: 404, message: "..." } }]
1
2
3
4
5
output = await g.sys.system.multi_tenant_instances_updated([
    MultiTenantInstanceUpdated('crm', 'acme'),
    MultiTenantInstanceUpdated('billing', 'acme'),
])
# [{ success: true, data: true }, { success: false, data: false, error: { code: 404, message: "..." } }]
1
2
3
4
5
$output = $g->sys->system->multiTenantInstancesUpdated([
    new MultiTenantInstanceUpdated('crm', 'acme'),
    new MultiTenantInstanceUpdated('billing', 'acme'),
]);
// [{ success: true, data: true }, { success: false, data: false, error: { code: 404, message: "..." } }]
1
2
3
4
5
var output = await g.Sys.System.MultiTenantInstancesUpdated([
    new MultiTenantInstanceUpdated("crm", "acme"),
    new MultiTenantInstanceUpdated("billing", "acme"),
]);
// [{ success: true, data: true }, { success: false, data: false, error: { code: 404, message: "..." } }]
1
2
3
4
5
6
7
8
output, err := g.Sys.System.MultiTenantInstancesUpdated([]am.MultiTenantInstanceUpdated{
    am.MultiTenantInstanceUpdated{InstanceName: "crm", Username: "acme"},
    am.MultiTenantInstanceUpdated{InstanceName: "billing", Username: "acme"},
})
if err != nil {
    return nil, err
}
// [{ success: true, data: true }, { success: false, data: false, error: { code: 404, message: "..." } }]
1
2
3
4
5
let output = g.sys.system.multi_tenant_instances_updated(vec![
    MultiTenantInstanceUpdated::new("crm", "acme"),
    MultiTenantInstanceUpdated::new("billing", "acme"),
])?;
// [{ success: true, data: true }, { success: false, data: false, error: { code: 404, message: "..." } }]
1
2
3
4
5
var output = g.sys.system.multiTenantInstancesUpdated(List.of(
    new MultiTenantInstanceUpdated("crm", "acme"),
    new MultiTenantInstanceUpdated("billing", "acme")
));
// [{ success: true, data: true }, { success: false, data: false, error: { code: 404, message: "..." } }]
1
2
3
4
5
val output = g.sys.system.multiTenantInstancesUpdated(listOf(
    MultiTenantInstanceUpdated("crm", "acme"),
    MultiTenantInstanceUpdated("billing", "acme"),
))
// [{ success: true, data: true }, { success: false, data: false, error: { code: 404, message: "..." } }]

Access, headers and errors

  • Over HTTP, a system API answers only once its settings open it : TOKEN_ACCESS (the token of an API user whose group grants this system API) or IS_PUBLIC. Without settings it is NO_ACCESS : only your code (g.sys) and the admin panel reach it.
  • The settings can also keep the answer in the cache, or ask for the token of a person (authProviders). Pre and post hooks run around it, as around any API.
  • It takes the request headers and answers the envelope. 401 : no valid token, or the API is NO_ACCESS. 403 : no group grants it. 400 : the body is wrong, and the message names the key.

Related : All APIs · System API settings · System APIs from code