【问题标题】:Micronaut-Core: How to create dynamic endpointsMicronaut-Core:如何创建动态端点
【发布时间】:2021-11-02 16:13:57
【问题描述】:

简单的问题。是否可以在没有@Endpoint 的情况下创建端点? 我想通过文件并根据其上下文的内容创建相当动态的端点。

谢谢!


更新我的想法。我想创建一个插件系统之类的东西,以使我的应用程序更易于维护和未来的功能。

值得一提的是,我正在将 Micronaut 与 Kotlin 一起使用。现在我有固定定义的端点,它与我的命令脚本相匹配。

我的描述文件将在/src/main/resources

我有以下示例描述文件的样子。

ENDPOINT: GET /myapi/customendpoint/version
COMMAND: """
#!/usr/bin/env bash

# This will be executed via SSH and streamed to stdout for further handling
echo "1.0.0"
"""
# This is a template JSON which will generate a JSON as production on the endpoint
OUTPUT: """
{
  "version": "Server version: $RESULT"
}
"""

我希望如何使它与应用程序一起工作。

import io.micronaut.docs.context.events.SampleEvent
import io.micronaut.context.event.StartupEvent
import io.micronaut.context.event.ShutdownEvent
import io.micronaut.runtime.event.annotation.EventListener

@Singleton
class SampleEventListener {
    /*var invocationCounter = 0

    @EventListener
    internal fun onSampleEvent(event: SampleEvent) {
        invocationCounter++
    }*/

    @EventListener
    internal fun onStartupEvent(event: StartupEvent) {
        // 1. I read all my description files
        // 2. Parse them (for what I created a parser)
        // 3. Now the tricky part, how to add those information to Micronaut Runtime
        
        val do = MyDescription() // After I parsed
        // Would be awesome if it is that simple! :)
        Micronaut.addEndpoint(
          do.getEndpoint(), do.getHttpOption(),
          MyCustomRequestHandler(do.getCommand()) // Maybe there is a base class for inheritance?
        )
    }

    @EventListener
    internal fun onShutdownEvent(event: ShutdownEvent) {
        // shutdown logic here
    }
}

【问题讨论】:

  • 文件来自哪里,您打算如何指定端点路径和实现?您能否更明确地描述一下您的具体情况?
  • 嗨@tmarwen,它只是资源中的一个文本文件,我将在其中描述端点。在启动时,我会阅读所有这些描述文件,然后这是我的问题,我会从 micronaut 调用一些东西来添加这些端点。我没有找到可以在运行时添加这些信息的基类。比如什么操作,端点以及它应该调用什么。
  • 请您更新您的帖子,并提供一个草稿示例,说明您的项目结构(属性和来源)以及您打算如何实现绑定(属性文件 -> 方法处理程序)。$跨度>
  • 是的,我更新了我的帖子以帮助澄清我的想法。 @tmarwen 我希望它可以帮助您理解我。 :)

标签: kotlin micronaut micronaut-rest


【解决方案1】:

您可以创建一个自定义RouteBuilder,它将在运行时注册您的自定义端点:

@Singleton
class CustomRouteBuilder extends DefaultRouteBuilder {

    @PostConstruct
    fun initRoutes() {
        val do = MyDescription();
        val method = do.getMethod();
        val routeUri = do.getEndpoint();
        val routeHandle = MethodExecutionHandle<Object, Object>() {
            // implement the 'MethodExecutionHandle' in a suitable manner to invoke the 'do.getCommand()'
        };
        buildRoute(HttpMethod.parse(method), routeUri, routeHandle);
    }
}

请注意,虽然这仍然可行,但最好考虑另一种扩展路径,因为该解决方案违背了作为 AOT 编译框架的整个 Micronaut 理念。

【讨论】:

  • 这看起来很棒!我不确定我的计划是否适用于 AOP。但也许有一个解决方案。你有什么方法可以告诉我 AOP 如何与 RequestHandler 一起工作吗?喜欢最小版本?
  • 你的意思是自定义RequestHandler?这将紧密依赖于上下文,您不应该走那么远,因为 Micronaut 将再次迫使您返回到编译时定义的依赖项。
  • 使用自定义 RequestHandler,我的意思是一种使用 AOP 处理我的个人请求的方法。你有想法吗?我想验证你的第一个答案(它已经看起来很整洁,但不像 Micronaut 那样)......也许如你所说,第二种方法更可行。 :)
  • 如果注释驱动的方法可以作为解决方案设计接受,那么可以。您可以拥有一个可以驱动可执行点(方法)的自定义注释。
  • 请给我一个小例子吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-14
  • 2011-05-31
  • 2015-05-10
  • 1970-01-01
  • 2011-11-15
相关资源
最近更新 更多