Files
2025-11-17 18:45:35 +01:00

64 lines
3.0 KiB
Markdown

# Lowcoder backend plugin system
This is an ongoing effort to refactor current plugin system based on pf4j library.
## Reasoning
1. create a cleaner and simpler plugin system with clearly defined purpose(s) (new endpoints, new datasource types, etc..)
2. 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)
3. 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)
```yaml
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:
```java
@EndpointExtension(uri = <endpoint uri>, method = <HTTP method>)
public EndpointResponse <handler name>(EndpointRequest request)
{
... your endpoint logic implementation
}
```
- TODO: class(es) impelemting **LowcoderDatasource** interface