-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Embedding spec into generated code #102
Comments
I definitely agree that it generally makes sense for applications to expose the schema they were built with on an endpoint (and generally I expect them to additionally expose rendered docs using redoc / whatever) With regards to #81 I was imagining something that would act as a convenience method for doing this, where you could optionally provide a route to expose the schema and rendered docs. I'm not 100% sure what that interface should look like yet, or when I'll get to it though. The way I currently tend to structure my projects looks something like:
And I'd include the With the revised approach of providing a
(adjust route / filepath / read file content once at startup / etc as appropriate) The other approach I've taken in the past has been to have a centralized/mono repository of openapi definitions such that the content of the definition gets pulled at the time of generation. In this instance I'd probably be inclined to just In the golang example you linked, I imagine the motivation for embedding as a base64 string is related to wanting to have a single static binary to ship (though I think using the recent stdlib addition https://pkg.go.dev/embed would make more sense now - you can still do stuff like only gzip it once if you really want, though I'd be surprised if the endpoint was getting called often enough to need to bother). Are you doing some kind of bundling or making use of https://nodejs.org/api/single-executable-applications.html that makes embedding the definition into the source code particularly desirable? Generally I think it works out better in terms of VCS history to keep it as a separate flat file if possible. |
I will be making use of pkg (https://github.com/vercel/pkg) in order to ship the app as a single binary, so it would make sense in this case, and I haven't yet but would probably make use of the same system for docker, depends on the how big the image ends up being and if there is need to make it smaller, as the pkg can be pretty big on their own. I generally store the openapi file in a folder in the root of the project so As for golang, I agree it's mostly done for portability, though I wonder if it's also done to reduce IO access as in not having to read a file and always have it in memory and cached, for quick access. What's your thoughts on the format that is served? I have come across a few projects that seem to only support generating clients from |
In the case of using Had a quick go at testing it out (was actually considering using Eg: here's an implementation serving the spec + redoc from one of my projects // ./src/withDocs.ts
import KoaRouter from "@koa/router"
import * as fs from "node:fs"
import path from "node:path"
export function withDocs(router: KoaRouter): KoaRouter {
router.get("/openapi.yaml", (ctx) => {
ctx.body = fs.readFileSync(path.join(__dirname, "../openapi.yaml"))
ctx.status = 200
})
router.get("/docs", (ctx) => {
ctx.body = `
<!DOCTYPE html>
<html>
<head>
<title>Docs</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
<style>
body {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<redoc spec-url='./openapi.yaml'></redoc>
<script src="https://cdn.redoc.ly/redoc/v2.1.3/bundles/redoc.standalone.js" integrity="sha384-R8e5ippgVo+kphHRsZE026R4rLIN/ORakEnRnOJ3S7BauiXHeD2EnvDpCcPYV4O/" crossorigin="anonymous"></script>
</body>
</html>
`
ctx.status = 200
})
return router
}
I'd probably ideally support serving either Most tools that consume this stuff tend to be fine with either though in my experience so might not matter too much.
I'd expect the Linux filesystem cache to basically already be doing this, and honestly can't think of many use cases for a highly optimized endpoint to retrieve the spec, as I'd generally expect it to receive very low traffic. |
This should definitely be it's own issue (coming from this issue) and this shouldn't be strictly related to #81.
So I have used other projects (mainly golang related) for openapi, and I was spoiled with the option of having the spec embedded into the server via base64 encoding. I'll provide this link here, that gives a good example of how that may look.
Unlike issue #81 this is not about providing documentation, but rather exposing the openapi schema itself, which can be served by the application itself, allowing someone to generate a client from that schema for the exact version of software that is hosting it. I've personally always found this way of doing it to be fitting for almost all apps that I have written using openapi.
Now I am not sure how involved you want this process to be, I personally would be fine with having it generated and a few helper functions to decode it, cache it, and then provide a function to get the cached contents of which could be served on any endpoint I wish without any forced requirements. However maybe you want the process to be more controlled, and maybe you have some function that takes an endpoint string, and then the library handles serving it up on that endpoint, with very little effort on the developer using it.
I hope this is something that makes it into the library in some way, as I see it being very beneficial.
The text was updated successfully, but these errors were encountered: