Swagger Does not pull schema definitions for routes.
cjrutherford opened this issue · comments
Documentation on the Docs module is kind of sparse to begin with. Is there a way that we could use a decorator to mark a class as a schema for swagger? I'm a little new to contributing, but I've been using Kiwi for several months now. If you show me the files to modify, and maybe how you're picking up schemas now, I can try to implement and PR this.
Hi man, how are you?
Sure let me know what do you want to do specifically and I can help you.
I'm well, thanks, I want work out how kiwi is detecting schemas to build the swagger json file. I've defined the types my routes are expecting and decorated the properties with class-validator, but in the swagger ui, I get errors about schemas not being defined. I was wondering if you could delve into that a bit.
essentially I want to be able to provide a decorator for a TS class that marks it as a schema Definition similar to the implementation in NestJS.
@ApiModel()
class Type{
@IsNumber()
userId: number;
}
and those then get injected into the swagger.json
file so that we can simply provide the type to the controller method signature, AND have it operable in the swagger UI.
Hi, sorry for the delay.
Maybe you can collaborate on that.
The right place to do that is on https://github.com/ollita7/kiwi/blob/master/src/metadata/metadataStorage.ts file.
The method that creates the swagger file is generateDoc.
I will work on it in a few days but if you want to start working on it I will apreciate it.
I want to give a little bit more information regarding the issue that brought this up. We're working on an API that appears the original developers didn't honor the type systems as much as one would think, and I'm trying to remove the use of any
and ensure that we know what each route is expecting, so I'm working out what's wrong with our api docs implementation through Kiwi.
To that end, I've attempted to type the routes on my controllers properly, and I started with this login route on the user controller.
@Post('/login')
public get(@Body() user: LoginRequest) {
console.dir(user);
return this.userManager.login(user.mail, user.password, user.rememberMe);
}
and I've created the LoginRequest
classs like this:
export class LoginRequest{
@IsString()
public mail: string;
@IsString()
public password: string;
@IsBoolean()
public rememberMe: boolean = false;
}
currently this class is in a location and file of my choosing. In testing this out with real world implications, I started modifying the compiled JS files in the node_modules of my project to determine what's going wrong.
First thing I notice is that in the initialization process, I see empty arrays for the constraint and validation metadatas.
Second is this the output when I modified it to save the routes object from the generateDocs
process to disk so I could then inspect. This is for the route I've documented above:
"/v1/user/login": {
"post": {
"executor": {},
"params": [
{
"order": 0,
"name": "body",
"type": "body",
"methodName": "get",
"className": "UserController",
"object": {}
}
],
"authorize": false,
"roles": []
}
},
So I guess, I want to know more about this process. it appears that Kiwi is using class-validator
to do a lot of the heavy lifting, and should I be putting my classes somewhere specific for it to be picked up for the OpenAPI docs?
Let me do some work and let you know!
Hi @cjrutherford I created a new version so now you can use nested objects
This example will help you.
export class AddressModel {
@IsString() public street: string;
@IsNumber() public number: number;
}
export class UserModel {
@IsNumber() public id: number;
@IsString() public name: string;
@IsString() public lastname: string;
@IsNumber() public age: number;
@isObject(() => AddressModel) public address: AddressModel;
//@isay(() => AddressModel) public address: AddressModel[];
}
ohh I understand!
Right now kiwi is not adding your classes to the documentation unless you are using your class in a body method.
For example in this controller method UsermModel is going be added automatically to the documentation.
@Post('/create') public create(@Body() user: UserModel) { user.id = Utils.userList.length + 1; Utils.userList.push(user); return user; }
Le me know maybe we can schedule a call to explain more in detail.