使用openapi-generator生成ktor服务器存根的正确方法是什么

时间:2020-05-26 16:40:17

标签: maven kotlin ktor openapi-generator

当尝试从openapi生成ktor的服务器端存根时,对我的输出看起来并不真正有用。

我设置了一个示例项目on Github,可以在其中查看设置。因为我需要在实际项目中使用maven,所以我也在这里使用了它,但是我想这与其他生成方法没有什么区别。

POM的相关部分是这样的:

<build>
    ...

    <plugins>
        ...

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.6</version>
            <executions>
                <execution>
                    <id>resources</id>
                    <phase>compile</phase>
                    <goals><goal>copy-resources</goal></goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/classes</outputDirectory>
                        <resources>
                            <resource>
                                <directory>${project.basedir}/resources</directory>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

将生成以下内容:

  • 数据模型
  • 一个Paths.kt对象,包含ktor-locations格式的我的路线的路径
  • 将API实现为io.ktor.routing.Route扩展功能的示例存根
  • 一个完整的应用程序,包括配置,Dockerfile,Gradle文件等。

来自SpringBoot和Swagger,我有点困惑,因为如果您想创建一个实现实际业务逻辑的实际应用程序,那么这组文件并不是真正有用的。我本来希望某些默认实现包含仅需要实现/重写的单个方法。我意识到ktor内置没有DI,因此我也希望必须以某种方式扩展应用程序中的routing存根。

但是,使用这组生成的代码,我实际上只能使用数据模型和Paths.kt对象。我将拥有自己的应用程序和无法覆盖的默认实现,但需要自己完全重写。

所以我的问题是,如何设置实现openapi规范的正确ktor应用程序。我会错过任何东西还是真的只得到模型和Paths.kt一起使用?

修改

为了更加清晰:特别是对于我的应用程序的这些部分,我很高兴没有工具的支持:

fun Application.module(testing: Boolean = false) {
    // other setup

    routing {
        // some other interfaces I may have

        FooApiImpl()
    }
}
/**
 * This Api Implementation has to be written completely manually. No help from the generated Code...
 */
@KtorExperimentalLocationsAPI
fun Route.FooApiImpl() {
    get<Paths.getAllFoos> {
        call.respond(listOf(
            Foo( id = -1, bar = "hello"),
            Foo( id = -2, bar = "world")
        ))
    }

    // the path gets named after the first method, which is weird in my eyes.
    post<Paths.getAllFoos> {
        val foo = call.receive<Foo>()
        // fooService.save(foo)
        call.respond(foo)
    }

    delete<Paths.deleteFooById> { path ->
        val id = path.id
        // fooService.deleteById(id)
        call.respond(HttpStatusCode.NoContent)
    }
}

0 个答案:

没有答案