3.0 KiB
3.0 KiB
Lowcoder backend plugin system
This is an ongoing effort to refactor current plugin system based on pf4j library.
Reasoning
- create a cleaner and simpler plugin system with clearly defined purpose(s) (new endpoints, new datasource types, etc..)
- lowcoder does not need live plugin loading/reloading/unloading/updates, therefore the main feature of pf4j is rendered useless, in fact it adds a lot of complexity due to classloaders used for managing plugins (especially in spring/boot applications)
- simpler and easier plugin detection - just a jar with a class implementing a common interface (be it a simple pojo project or a complex spring/boot implementation)
How it works
The main entrypoint for plugin system is in lowcoder-server module with class org.lowcoder.api.framework.configuration.PluginConfiguration
It creates:
- LowcoderPluginManager bean which is responsible for plugin lifecycle management
- Adds plugin defined endpoints to lowcoder by creating pluginEndpoints bean
- TODO: Adds plugin defined datasources to lowcoder by creating pluginDatasources bean
lowcoder-plugin-api library
This library contains APIs for plugin implementations.
It is used by both, lowcoder API server as well as all plugins.
PluginLoader
The sole purpose of a PluginLoader is to find plugin candidates and load them into VM.
There is currently one implementation that based on paths - PathBasedPluginLoader, it:
- looks in folders and subfolders defined in application.yaml - entries can point to a folder or specific jar file. If a relative path is supplied, the location of lowcoder API server application jar is used as parent folder (when run in non-packaged state, eg. in IDE, it uses the folder where ServerApplication.class is generated)
common:
plugin-dirs:
- plugins
- /some/custom/path/myGreatPlugin.jar
- finds all jar(s) and inspects them for classes implementing LowcoderPlugin interface
- instantiates all LowcoderPlugin implementations
LowcoderPluginManager
The main job of plugin manager is to:
- register plugins found and instantiated by PluginLoader
- start registered plugins by calling LowcoderPlugin.load() method
- create and register RouterFunction(s) for all loaded plugin endpoints
- TODO: create and register datasources for all loaded plugin datasources
Plugin project structure
Plugin jar can be structured in any way you like. It can be a plain java project, but also a spring/boot based project or based on any other framework.
It is composed from several parts:
- class(es) implementing LowcoderPlugin interface
- class(es) implementing PluginEndpoint interface, containing endpoint handler functions marked with @EndpointExtension annotation. These functions must obey following format:
@EndpointExtension(uri = <endpoint uri>, method = <HTTP method>)
public EndpointResponse <handler name>(EndpointRequest request)
{
... your endpoint logic implementation
}
- TODO: class(es) impelemting LowcoderDatasource interface