Crear plugins personalizados
Crear plugins personalizados
Si necesitas rutas de API personalizadas o lógica en segundo plano, implementa un plugin de AppKit. La forma más rápida es usar la CLI:
# Interactivo
npx @databricks/appkit plugin create
# No interactivo
npx @databricks/appkit plugin create --placement in-repo --path plugins/my-plugin --name my-plugin --description "My plugin" --forcePara comprender mejor la estructura del plugin, continúa leyendo.
Ejemplo básico de plugin
Escribe el manifiesto en JSON, impórtalo y asócialo a una subclase de Plugin mediante static manifest. Expórtalo con toPlugin():
// my-plugin/manifest.json
{
"$schema": "https://databricks.github.io/appkit/schemas/plugin-manifest.schema.json",
"name": "my-plugin",
"displayName": "My Plugin",
"description": "A custom plugin",
"resources": {
"required": [
{
"type": "secret",
"alias": "apiKey",
"resourceKey": "api-key",
"description": "API key for external service",
"permission": "READ",
"fields": {
"scope": { "env": "MY_SECRET_SCOPE", "description": "Secret scope" },
"key": { "env": "MY_API_KEY", "description": "Secret key name" }
}
}
],
"optional": []
}
}// my-plugin/index.ts
import { Plugin, toPlugin, type PluginManifest } from "@databricks/appkit";
import manifest from "./manifest.json";
class MyPlugin extends Plugin {
static manifest = manifest as PluginManifest<"my-plugin">;
async setup() {
// Inicializa tu plugin
}
myCustomMethod() {
// Implementación
}
async shutdown() {
// Libera los recursos
}
exports() {
return {
myCustomMethod: this.myCustomMethod
}
}
}
export const myPlugin = toPlugin(MyPlugin);JSON es la superficie canónica de creación: es lo que lee appkit plugin sync al agregar los manifiestos de las templates. Para conocer el contrato completo del manifiesto v2.0 (recursos, descriptores de descubrimiento, reglas de scaffolding), consulta Manifiesto del plugin.
Recursos dependientes de la configuración
El manifiesto define los recursos como required (siempre necesarios) u optional (que pueden ser necesarios).
Para los recursos que pasan a ser obligatorios según la configuración del plugin, implementa un método estático
getResourceRequirements(config):
interface MyPluginConfig extends BasePluginConfig {
enableCaching?: boolean;
}
class MyPlugin extends Plugin<MyPluginConfig> {
static manifest = {
name: "myPlugin",
displayName: "My Plugin",
description: "A plugin with optional caching",
resources: {
required: [
{ type: "sql_warehouse", alias: "warehouse", resourceKey: "sqlWarehouse", description: "Query execution", permission: "CAN_USE", fields: { id: { env: "DATABRICKS_WAREHOUSE_ID" } } }
],
optional: [
// Se declara como opcional en el manifiesto para el análisis estático
{ type: "database", alias: "cache", resourceKey: "cache", description: "Query result caching (if enabled)", permission: "CAN_CONNECT_AND_CREATE", fields: { instance_name: { env: "DATABRICKS_CACHE_INSTANCE" }, database_name: { env: "DATABRICKS_CACHE_DB" } } }
]
}
} satisfies PluginManifest<"myPlugin">;
// Runtime: convierte los recursos opcionales en obligatorios según la configuración
static getResourceRequirements(config: MyPluginConfig) {
const resources = [];
if (config.enableCaching) {
// Cuando la caché está habilitada, Database pasa a ser obligatorio
resources.push({
type: "database",
alias: "cache",
resourceKey: "cache",
description: "Query result caching",
permission: "CAN_CONNECT_AND_CREATE",
fields: {
instance_name: { env: "DATABRICKS_CACHE_INSTANCE" },
database_name: { env: "DATABRICKS_CACHE_DB" },
},
required: true // Se marca como obligatorio en runtime
});
}
return resources;
}
}Este patrón permite:
- Que las herramientas estáticas (CLI, documentación) muestren todos los recursos posibles
- Que la validation en runtime exija los recursos según la configuration real
Puntos de extensión clave
- Inyección de rutas: implementa
injectRoutes()para añadir endpoints personalizados medianteIAppRouter - Hooks de ciclo de vida: sobrescribe los métodos
setup()yshutdown() - Servicios compartidos:
- Gestión de caché: accede al servicio de caché mediante
this.cache. ConsultaCacheConfigpara la configuración. - Telemetría: instrumenta tu plugin con trazas y métricas mediante
this.telemetry. ConsultaITelemetry.
- Gestión de caché: accede al servicio de caché mediante
- Interceptores de ejecución: usa
execute()yexecuteStream()conStreamExecutionSettingspara caché, reintentos y tiempos de espera automáticos, además de los atributos de span de telemetría (execution.context,caller.id)
Consumir tu plugin mediante código
Opcionalmente, puedes ofrecer una forma de consumir tu plugin mediante código usando el objeto AppKit.
Para ello, tu plugin debe implementar el método exports y devolver un objeto con los métodos que quieras exponer. Partiendo del ejemplo anterior, el plugin podría consumirse así:
const AppKit = await createApp({
plugins: [
server({ port: 8000 }),
analytics(),
myPlugin(),
],
});
AppKit.myPlugin.myCustomMethod();Consulta la referencia de la API de Plugin para ver la documentación completa.