Créer des plugins personnalisés
Créer des plugins personnalisés
Si vous avez besoin de routes d'API personnalisées ou de logique en arrière-plan, implémentez un plugin AppKit. Le plus rapide est de passer par la CLI :
# Interactif
npx @databricks/appkit plugin create
# Non interactif
npx @databricks/appkit plugin create --placement in-repo --path plugins/my-plugin --name my-plugin --description "My plugin" --forcePour mieux comprendre la structure d'un plugin, poursuivez votre lecture.
Exemple de plugin simple
Rédigez le manifeste en JSON, importez-le, puis associez-le à une sous-classe de Plugin via static manifest. Exportez-le avec 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() {
// Initialisez votre plugin
}
myCustomMethod() {
// Implémentation à compléter
}
async shutdown() {
// Libérez les ressources
}
exports() {
return {
myCustomMethod: this.myCustomMethod
}
}
}
export const myPlugin = toPlugin(MyPlugin);JSON est le format d'écriture de référence : c'est ce que lit appkit plugin sync lorsqu'il agrège les manifestes des modèles. Pour le contrat complet du manifeste v2.0 (ressources, descripteurs de découverte, règles de génération d'ossature), voir Manifeste de plugin.
Ressources dépendantes de la configuration
Le manifeste déclare les ressources comme required (toujours nécessaires) ou optional (potentiellement nécessaires).
Pour les ressources qui deviennent obligatoires selon la configuration du plugin, implémentez une méthode statique
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: [
// Déclarée comme facultative dans le manifeste pour l'analyse statique
{ 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 : convertit les ressources facultatives en ressources requises selon la configuration
static getResourceRequirements(config: MyPluginConfig) {
const resources = [];
if (config.enableCaching) {
// Lorsque la mise en cache est activée, Database devient requise
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 // Marquée comme requise au runtime
});
}
return resources;
}
}Ce modèle permet :
- aux outils statiques (CLI, documentation) d'afficher toutes les ressources possibles ;
- à la validation au runtime d'imposer les ressources en fonction de la configuration réelle.
Points d'extension clés
- Injection de routes : implémentez
injectRoutes()pour ajouter des endpoints personnalisés à l'aide deIAppRouter - Hooks de cycle de vie : surchargez les méthodes
setup()etshutdown() - Services partagés :
- Gestion du cache : accédez au service de cache via
this.cache. VoirCacheConfigpour la configuration. - Télémétrie : instrumentez votre plugin avec des traces et des métriques via
this.telemetry. VoirITelemetry.
- Gestion du cache : accédez au service de cache via
- Intercepteurs d'exécution : utilisez
execute()etexecuteStream()avecStreamExecutionSettingspour bénéficier automatiquement de la mise en cache, des nouvelles tentatives, du délai d'expiration et des attributs de span de télémétrie (execution.context,caller.id)
Utiliser votre plugin par programmation
Vous pouvez, si vous le souhaitez, permettre l'utilisation de votre plugin par programmation via l'objet AppKit.
Pour cela, votre plugin doit implémenter la méthode exports, qui renvoie un objet contenant les méthodes que vous souhaitez exposer. En reprenant l'exemple précédent, le plugin s'utiliserait comme suit :
const AppKit = await createApp({
plugins: [
server({ port: 8000 }),
analytics(),
myPlugin(),
],
});
AppKit.myPlugin.myCustomMethod();Consultez la référence de l'API Plugin pour la documentation complète.