sveltekit-zero-api
sveltekit-zero-api copied to clipboard
feat: export API documentation
Not sure how to approach this yet, so suggestions are welcome
Essentially, the ability to do something ála npx sveltekit-zero-api export
Current implementation idea is an algorithm to check interfaces and return functions - where input/output examples will be comments in one way or another
I'm expecting to work on this towards early 2023
Currently considering this approach
// New
class Get {
query = {
length: { type: Number, ex: 100, comment: 'The return length of documents' },
offset: { type: Number, ex: 0, comment: 'The offset, of which the document is fetched' },
sortNew: { type: Boolean, ex: true, comment: 'Whether to sort by new' },
// Enum like
level: { type: [['any', 'info', 'warn', 'error', 'assert']], ex: ['info'], comment: 'Which level of log to get' }
}
}
// Current
interface Get {
query: {
length?: number
offset?: number
sortNew?: boolean
level?: LogLevel
type?: LogType
filters?: Parameters<typeof Log.find>[0]
}
}
Inspired from mongoose and typegoose. Having classes would allow the use of constructors to identify each item. The only downside would be the requirement of typing any objects below it.
For instance in
interface Post {
body: {
product: Proudct
}
}
The product would also need a class. In typegoose this isn't an issue, since Zero API could just derive from the typegoose class which you create:
// Only contains the document input/output values.
class ProductProperties { ... }
// Contains model methods etc.
class Product extends ProductProperties { ... }
const ProductModel = getModelFromClass(Product)
Now sure the similarity compares to other databases.
Another selling point to this idea would be that a) We can attach decorators for documentation items such as comments or example values b) querySpread can make use of the class, to identify incorrect types for you
Ultimatively, Zero API would still allow a simple interface, if an exported documentation isn't an interest @ e.g. prototyping
Using TypeScript parser and an AST parser, I'll attempt to get the returned types of endpoints. The endpoint input and output will be exported locally to a JSON-file specified in the configs. This JSON file will contain all API Endpoints their input and output values, and examples if you provided them in your code.
Interfaces will stay the same as they are now. I'm planning for this feature to support ZOD.
I'm bringing this to life in 2023. I'm booked with work for a few months😬
I woke up after a very vivid dream from my cat meowing - and literally quite out of nowhere got an idea how to handle API documentation.
Simply structure endpoints using a function:
import { endpoint } from 'sveltekit-zero-api'
export const POST = endpoint({
// Documentation goes here
}, (event: KitEvent<...>) => {
})
The endpoint returns a function with a single argument. If the argument is of Symbol('documentation'), the function will return documentation. Otherwise return the actual endpoint.
If we're smart, we can get rid of KitEvent type and even avoid defining a interface Post by having it come from the structure within the documenting part:
export const POST = endpoint({
body: { ... },
queries: { ... },
examples: [...],
// etc... anything that documents
}, (event) => {
})
In terms of inferring objects and what not: I am developing x-classes which has been on my scope for a long time — and I will try to make them synergize without depending on each other.
For other libraries we may just have independent libraries that have functions to handle documentation; sveltekit-zero-api/zod, sveltekit-zero-api/class-validator.
The contents of documentation still needs to be thought through. I'll think about it for now.
The second parameter is either a function as you're used to, or be rest parameters that matches zero-apis pipe function:
export const POST = endpoint({ ... }, (event) => {
})
// or
export const POST = endpoint({ ... },
authGuard('admin'),
parseJSON<Post>,
(event) => {
...
}
)
I personally think this is a great idea. As soon as x-classes has gotten to where I am satisfied, I will probably return to this and follow through. Happy coding🦒
My last comments oversight is that we still need the response types, and are not easily inferred as a first argument to a function. There might be a need for example responses, which could be provided by that first argument.
I personally think inferring responses with their associated types would be neater. However, there's some complexity in inferring those types, and I don't have experience working with parsers as mentioned in https://github.com/Refzlund/sveltekit-zero-api/issues/3#issuecomment-1281950883
However, I still wish to see this come to life before the end of the year, so🦒🕺🤷
FYI reworking sveltekit-zero-api with my improved understanding of TypeScript in order to provide better types.
This rework will allow the library to be used in other libraries. I have tested the new types, and they will solve this issue specifically.
A better type system allows for tsc --declaration on +server.ts, and the input and output can basically be extracted from here. A limitation might be classes, as they will in the .d.ts-file be referenced via an inline import statement.
Simplifyng the object may or may not help.
KitEvent<{ body: { user: Simplify<User> } }>
Still need to experiment with this approach.
Rather than using a Simplify type, a ToJSON<T> that respects an Objects toJSON method (as described "for other objects" here), otherwise only uses the primitive types.
* Note: Recursive types will end up becoming any from my testing.