[[patterns]] == Patterns [[scoped-services]] === Scoped services Whenever Kibana needs to get access to data saved in Elasticsearch, it should perform a check whether an end-user has access to the data. The Kibana Platform introduced a handler interface on the server-side to perform that association internally. Core services, that require impersonation with an incoming request, are exposed via `context` argument of {kib-repo}/blob/8.9/src/core/packages/http/server/src/router/request_handler.ts[the request handler interface]. [source,js] ---- async function handler(context, req, res) { const data = await context.core.elasticsearch.client.asCurrentUser('ping'); } ---- The {kib-repo}/blob/8.9/src/core/packages/http/server/src/router/request_handler.ts[request handler context] exposes the following scoped *core* services: * {kib-repo}/blob/8.9/src/core/packages/saved-objects/api-server/src/saved_objects_client.ts[`context.savedObjects.client`] * {kib-repo}/blob/8.9/src/core/packages/elasticsearch/server/src/client/scoped_cluster_client.ts[`context.elasticsearch.client`] * {kib-repo}/blob/8.9/packages/core/ui-settings/core-ui-settings-server/src/ui_settings_client.ts[`context.uiSettings.client`] ==== Declare a custom scoped service Plugins can extend the handler context with a custom API that will be available to the plugin itself and all dependent plugins. For example, the plugin creates a custom Elasticsearch client and wants to use it via the request handler context: [source,typescript] ---- import type { CoreSetup, RequestHandlerContext, IScopedClusterClient } from '@kbn/core/server'; interface MyRequestHandlerContext extends RequestHandlerContext { myPlugin: { client: IScopedClusterClient; }; } class MyPlugin { setup(core: CoreSetup) { const client = core.elasticsearch.createClient('myClient'); core.http.registerRouteHandlerContext('myPlugin', (context, req, res) => { return { client: client.asScoped(req) }; }); const router = core.http.createRouter(); router.get( { path: '/api/my-plugin/', validate: … }, async (context, req, res) => { // context type is inferred as MyPluginContext const data = await context.myPlugin.client.asCurrentUser('endpoint'); } ); } ----