Is your feature request related to a problem? Please describe.
What do you think about the possibility to automatically generate your api documentation in development mode?
Describe the solution you'd like
I don't if you know me, but I don't like to depend on external libraries and I usually develop my own libraries because this project is a laboratory, so the main idea is to create a strategy to generate api documentation automatically only when you are developing.
Describe alternatives you've considered
Everything happens in the adapter layer, specifically in each controller, then there we can add the configuration of each endpoint that to be exposed by our api solution.
So let me to start to expose the idea:
initializeRoutes(router: IRouter): void {
// Current way to registering routes
this.router = router();
this.router.get("/v1/feelings", this.getFeelingText);
// New proposal to register routes
this.setRouter(router());
this.addRoute({
method: HttpMethodEnum.GET,
path: "/v1/feelings",
handlers: [this.getFeelingText],
produces: [
{
applicationStatus: applicationStatus.SUCCESS,
httpStatus: HttpStatusEnum.SUCCESS,
},
{
applicationStatus: applicationStatus.USER_NOT_FOUND,
httpStatus: HttpStatusEnum.NOT_FOUND,
},
],
});
}
As you can see, the next way to register a new route is through the method addRoute
and in this method we can set properties like:
method
, path
, handlers
, contentType
and produces
as an object array that it enable us to configure another options like applicationStatus
code and the corresponding httpStatus
code (Yes, you no need to register it in statusMapping object), even the request and the same way the response types.
And here is where there is a problem with the description for response and request types because the way TypeScript works does not allow us to create the description of these types in an easy way so we will have to create objects that we help us to describe the Types that our endpoints receive and later generate a JSON format to specify the documentation of our APIs.
So, to do it I have the next proposal:
In initializeRoutes from AuthController with the next way to register a route, we have as following:
initializeRoutes(router: IRouter): void {
this.setRouter(router());
this.addRoute({
method: HttpMethodEnum.POST,
path: "/v1/auth/login",
handlers: [this.login],
produces: [
{
applicationStatus: applicationStatus.SUCCESS,
httpStatus: HttpStatusEnum.SUCCESS,
},
{
applicationStatus: applicationStatus.UNAUTHORIZED,
httpStatus: HttpStatusEnum.UNAUTHORIZED,
},
],
description: "Login user",
apiDoc: {
description: "Login user",
contentType: HttpContentTypeEnum.APPLICATION_JSON,
requireAuth: false,
schema: new ResultTDescriber<TokenDto>({
name: TokenDto.name,
type: PropTypeEnum.OBJECT,
props: {
data: new TypeDescriber<TokenDto>({
name: TokenDto.name,
type: PropTypeEnum.OBJECT,
props: {
token: {
type: PropTypeEnum.STRING,
},
expiresIn: {
type: PropTypeEnum.NUMBER,
},
},
}),
error: {
type: PropTypeEnum.STRING,
},
message: {
type: PropTypeEnum.STRING,
},
statusCode: {
type: PropTypeEnum.STRING,
},
success: {
type: PropTypeEnum.BOOLEAN,
},
},
}),
},
});
}
So adding our description types for request and response we can to have the following:
{
"openapi": "3.1.0",
"title": "NodeTSkeleton API",
"version": "1.0.0",
"description": "Api documentation for NodeTSkeleton project",
"contact": {
"name": "TSK Support",
"url": "https://github.com/harvic3/nodetskeleton",
"email": "[email protected]"
},
"license": {
"name": "MIT",
"identifier": "MIT"
},
"servers": [
{
"url": "localhost:3003",
"description": "Local server"
}
],
"paths": {
"/v1/auth/login": {
"post": {
"description": "Login user",
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResultT<TokenDto>"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResultT<TokenDto>"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"TokenDto": {
"token": "string",
"expiresIn": "number"
},
"ResultT<TokenDto>": {
"message": "string",
"statusCode": "string",
"error": "string",
"success": "boolean",
"data": {
"$ref": "#/components/schemas/TokenDto"
}
}
}
}
}
Additional context
So, this was the way that was implemented to generate the documentation of our solution at the API level.
So guest what do you think, do you have any suggestions, do you see any improvements? I read you!!
Keep in mind that:
- If this functionality is integrated it would be optional, because you can continue working normally.
- It only works in development mode.
- The idea in the future is to use the JSON file to build an HTML template that exposes the API documentation via web in development mode using openApi standard.
The branch for this feature is:
https://github.com/harvic3/nodetskeleton/tree/feature/routing-proposal