Skip to main content

Plugin Usage Guide

In Lynx, a plugin is not just another SDK dependency. It is a capability module that joins the shared runtime, is registered into the global plugin factory, and is then assembled by the plugin manager during application startup.

This page focuses on the code-backed integration path you will use for most Lynx plugins: correct module path, correct config prefix, registration mechanism, and the public API you actually obtain after startup.

The integration chain you should keep in mind

For most Lynx plugins, the runtime path is:

  1. add the correct Go module
  2. configure the matching prefix
  3. anonymous-import the module so it registers itself into factory.GlobalTypedFactory()
  4. let boot.NewApplication(wireApp).Run() assemble the runtime
  5. obtain the capability through the plugin's exported Getter or through the plugin manager

That chain matters because configuration alone does not load a plugin, and importing a package alone does not initialize it. Both registration and startup assembly have to happen.

1. Add the correct module

The current repository family is mostly split into standalone plugin modules. In practice, the imports you want today look more like this:

# framework core / built-in capabilities
go get github.com/go-lynx/lynx

# service plugins
go get github.com/go-lynx/lynx-http
go get github.com/go-lynx/lynx-grpc

# storage and cache
go get github.com/go-lynx/lynx-redis
go get github.com/go-lynx/lynx-mongodb
go get github.com/go-lynx/lynx-elasticsearch
go get github.com/go-lynx/lynx-mysql
go get github.com/go-lynx/lynx-pgsql
go get github.com/go-lynx/lynx-mssql

# messaging
go get github.com/go-lynx/lynx-kafka
go get github.com/go-lynx/lynx-rabbitmq
go get github.com/go-lynx/lynx-rocketmq
go get github.com/go-lynx/lynx-pulsar

# config / governance / observability
go get github.com/go-lynx/lynx-polaris
go get github.com/go-lynx/lynx-nacos
go get github.com/go-lynx/lynx-apollo
go get github.com/go-lynx/lynx-etcd
go get github.com/go-lynx/lynx-tracer
go get github.com/go-lynx/lynx-swagger
go get github.com/go-lynx/lynx-sentinel

# distributed capability
go get github.com/go-lynx/lynx-seata
go get github.com/go-lynx/lynx-dtm
go get github.com/go-lynx/lynx-redis-lock
go get github.com/go-lynx/lynx-etcd-lock

Two important notes:

  • the documentation should follow the module path in each plugin repository's go.mod
  • some capabilities still live in the main repository, such as TLS Manager, while most business-facing plugins live in standalone modules

2. Add the matching config prefix

Each plugin registers with a concrete config prefix in code. That prefix is what the runtime scans during InitializeResources.

Examples from the current codebase:

CapabilityModuleConfig prefix
HTTP servergithub.com/go-lynx/lynx-httplynx.http
gRPC servicegithub.com/go-lynx/lynx-grpclynx.grpc.service
gRPC clientgithub.com/go-lynx/lynx-grpclynx.grpc.client
Redisgithub.com/go-lynx/lynx-redislynx.redis
Elasticsearchgithub.com/go-lynx/lynx-elasticsearchlynx.elasticsearch
MongoDBgithub.com/go-lynx/lynx-mongodblynx.mongodb
Polarisgithub.com/go-lynx/lynx-polarislynx.polaris
Apollogithub.com/go-lynx/lynx-apollolynx.apollo
Etcdgithub.com/go-lynx/lynx-etcdlynx.etcd
Tracergithub.com/go-lynx/lynx-tracerlynx.tracer
Sentinelgithub.com/go-lynx/lynx-sentinellynx.sentinel
Seatagithub.com/go-lynx/lynx-seatalynx.seata
DTMgithub.com/go-lynx/lynx-dtmlynx.dtm
Etcd Lockgithub.com/go-lynx/lynx-etcd-locklynx.etcd-lock
TLSgithub.com/go-lynx/lynx/tlslynx.tls
RabbitMQgithub.com/go-lynx/lynx-rabbitmqrabbitmq
RocketMQgithub.com/go-lynx/lynx-rocketmqrocketmq

For example:

lynx:
http:
addr: 0.0.0.0:8000
timeout: 5s

redis:
addrs:
- 127.0.0.1:6379
password: ""
db: 0

tracer:
enable: true
addr: "127.0.0.1:4317"

2.1 Read plugin docs together with the official template

One recurring source of confusion is that plugin pages describe a capability in isolation, while the official template shows how multiple plugins are composed in one runnable service.

lynx-layout/configs/bootstrap.local.yaml currently uses:

  • lynx.http
  • lynx.grpc.service
  • lynx.mysql
  • lynx.redis

lynx-layout/configs/bootstrap.yaml currently uses:

  • lynx.application
  • lynx.polaris

That is important because the template is the most concrete example of which prefixes and shapes are actually used together in current Lynx projects.

When template code and a plugin page feel different, read them this way:

  • template config answers "what do I put in a runnable project right now?"
  • plugin page answers "what does this one plugin support in full?"
  • getter examples in template code answer "what do I call after startup?"

2.2 Understand the template buckets before adding plugins

The current official template is easier to reason about when you treat plugins in three groups:

  • enabled in local bootstrap: HTTP, gRPC server, MySQL, Redis
  • enabled in governance bootstrap: application metadata plus Polaris
  • not enabled by default: most MQ, config-center, lock, protection, docs, and TLS plugins

One special case sits between those groups: tracer is already imported by the template, but not made explicit in the default local config.

This simple classification prevents a lot of confusion:

  • if the template already uses it, match the template first
  • if the template does not use it, read the plugin page as an opt-in integration path
  • if the template only pre-wires it, expect one more explicit config step before the behavior becomes visible

3. Register the plugin with an anonymous import

Most plugins register themselves through factory.GlobalTypedFactory().RegisterPlugin(...) in init(). That means you usually need an anonymous import:

import (
_ "github.com/go-lynx/lynx-http"
_ "github.com/go-lynx/lynx-grpc"
_ "github.com/go-lynx/lynx-redis"
_ "github.com/go-lynx/lynx-tracer"
)

This is not a cosmetic detail. Without importing the module, the plugin factory registration does not happen, so the plugin manager has nothing to assemble even if configuration exists.

4. Let startup assemble the runtime

The recommended startup entry remains:

func main() {
if err := boot.NewApplication(wireApp).Run(); err != nil {
panic(err)
}
}

At this stage, Lynx:

  • reads bootstrap configuration
  • resolves plugin load order and dependencies
  • initializes plugin resources
  • runs startup tasks
  • exposes shared resources and service endpoints

That is why plugin documentation should be read in runtime terms, not only in SDK terms.

5. Obtain the capability after startup

There are three common patterns in the current codebase.

Pattern A: direct Getter returning the runtime-owned object

This is common for service and datastore plugins:

httpServer, err := lynxhttp.GetHttpServer()
grpcServer, err := lynxgrpc.GetGrpcServer(nil)

rdb := redis.GetUniversalRedis()
es := elasticsearch.GetElasticsearch()
db := mongodb.GetMongoDBDatabase()

Pattern B: Getter returning the plugin object itself

This is common when the plugin exposes richer methods than one client handle:

plugin, err := polaris.GetPolarisPlugin()
instances, err := polaris.GetServiceInstances("user-service")
cfg, err := polaris.GetConfig("application.yaml", "DEFAULT_GROUP")

Pattern C: obtain by plugin manager and assert the concrete type or interface

This is common for modules that are intentionally more dynamic:

plugin := app.Lynx().GetPluginManager().GetPlugin("dtm.server")
dtmClient := plugin.(*dtm.DTMClient)

mqPlugin := app.Lynx().GetPluginManager().GetPlugin("rabbitmq")
client := mqPlugin.(rabbitmq.ClientInterface)

Public entry points you will actually use

The following APIs are already present in code and are worth knowing because they are better than guessing.

CapabilityPublic entry points
HTTPhttp.GetHttpServer()
gRPC servicegrpc.GetGrpcServer(nil)
Redisredis.GetRedis(), redis.GetUniversalRedis()
MongoDBmongodb.GetMongoDB(), mongodb.GetMongoDBDatabase(), mongodb.GetMongoDBCollection()
Elasticsearchelasticsearch.GetElasticsearch(), elasticsearch.GetElasticsearchPlugin(), elasticsearch.GetIndexName()
Pulsarpulsar.GetPulsarClient()
Polarispolaris.GetPolarisPlugin(), polaris.GetServiceInstances(), polaris.GetConfig(), polaris.GetMetrics()
Sentinelsentinel.GetSentinel(), sentinel.GetMetrics(), sentinel.GetResourceStats()
Seataseata.GetPlugin()
TLScertificate provider methods such as GetCertificate(), GetPrivateKey(), GetRootCACertificate()

When a plugin document names a Getter, it should be read as a stable integration entry, not as a random convenience helper.

Plugin names you may see in the plugin manager

If you inspect the plugin manager directly, the current codebase uses names such as:

CapabilityPlugin manager name
HTTPhttp.server
gRPC servicegrpc.service
Redisredis.client
Elasticsearchelasticsearch.client
MongoDBmongodb.client
Polarispolaris.control.plane
Apolloapollo.config.center
Etcdetcd.config.center
Tracertracer.server
Seataseata.server
DTMdtm.server
Sentinelsentinel.flow_control
Etcd Locketcd.distributed.lock

This matters when you use GetPlugin(...) manually.

Scenario-oriented recommendations

NeedRecommended modulesCommon access pattern
HTTP APIlynx-httpGetHttpServer()
gRPC servicelynx-grpcGetGrpcServer(nil)
gRPC client subscriptionslynx-grpc client plugin / lynx/subscribeplugin manager or helper loader
Cache / shared statelynx-redisGetUniversalRedis()
Searchlynx-elasticsearchGetElasticsearch()
Document databaselynx-mongodbGetMongoDBDatabase()
SQL databaselynx-mysql / lynx-pgsql / lynx-mssqlSQL plugin Getter / provider
Config center / discoverylynx-polaris, lynx-nacos, lynx-apollo, lynx-etcdplugin API + runtime wiring
Messaginglynx-kafka, lynx-rabbitmq, lynx-rocketmq, lynx-pulsarplugin manager or exported Getter
Distributed transactionlynx-seata, lynx-dtmplugin object / helper APIs
Distributed locklynx-redis-lock, lynx-etcd-locklock helper APIs
API docs / tracing / flow controllynx-swagger, lynx-tracer, lynx-sentinelplugin API / middleware integration

Practical rules

  • use the real module path from the plugin repository, not guessed import paths
  • use the real config prefix from plugin code, not a hand-waved alias
  • remember that some plugins do not use a lynx.<name> prefix even though they are Lynx plugins, such as rabbitmq and rocketmq
  • prefer the exported Getter when it already exists; it is usually the intended public entry
  • drop down to GetPlugin(...) only when you need plugin-specific rich methods or dynamic integration
  • read plugin pages together with bootstrap configuration and runtime ordering, because many capabilities depend on startup sequence, not only config shape

Next steps