Swagger-ui 扁平化查询参数中的对象,但生成的 angular 客户端不会
Swagger-ui flattens object in query params, but the generated angular client doesn't
我的 spring 启动应用程序中有以下 Rest 函数
@SecuredMaster
@GetMapping(path = "/mitarbeiter")
@Operation(security = {@SecurityRequirement(name = "jwt")})
public Page<MitarbeiterListRow> getMitarbeiter(Pageable pageable, @RequestParam(defaultValue = "") String query) {
return mitarbeiterRepository.findAllByUsernameContainingIgnoreCaseOrEmailContainingIgnoreCase(pageable, query, query);
}
我使用 springdoc 生成 openapi3 yaml
// generate api docs
implementation 'org.springdoc:springdoc-openapi-ui:1.2.18'
implementation 'org.springdoc:springdoc-openapi-data-rest:1.2.18'
生成的 yaml 看起来像这样
然后我生成一个angular客户端
java -jar swagger-codegen-cli.jar generate -i http://localhost:8080/apidocs/v3/api-docs -l typescript-angular -o ../frontend/src/generated/swagger
生成的客户端如下所示
/**
*
*
* @param pageable
* @param query
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
public getMitarbeiter(pageable: Pageable, query?: string, observe?: 'body', reportProgress?: boolean): Observable<PageMitarbeiterListRow>;
public getMitarbeiter(pageable: Pageable, query?: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<PageMitarbeiterListRow>>;
public getMitarbeiter(pageable: Pageable, query?: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<PageMitarbeiterListRow>>;
public getMitarbeiter(pageable: Pageable, query?: string, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
if (pageable === null || pageable === undefined) {
throw new Error('Required parameter pageable was null or undefined when calling getMitarbeiter.');
}
let queryParameters = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()});
if (pageable !== undefined && pageable !== null) {
queryParameters = queryParameters.set('pageable', <any>pageable);
}
if (query !== undefined && query !== null) {
queryParameters = queryParameters.set('query', <any>query);
}
let headers = this.defaultHeaders;
// authentication (jwt) required
if (this.configuration.accessToken) {
const accessToken = typeof this.configuration.accessToken === 'function'
? this.configuration.accessToken()
: this.configuration.accessToken;
headers = headers.set('Authorization', 'Bearer ' + accessToken);
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'*/*'
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}
// to determine the Content-Type header
const consumes: string[] = [
];
return this.httpClient.get<PageMitarbeiterListRow>(`${this.basePath}/mitarbeiter`,
{
params: queryParameters,
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
}
);
}
当我使用生成的服务时,它会发出这样的请求:
但是当我使用 swagger 时 UI 它工作正常
为什么 swagger-ui 发出正确的请求而生成的 angular-client 却没有?
这是 typescript-angular 生成器的问题:
https://github.com/OpenAPITools/openapi-generator/issues/4404
已经创建了一个 Pull Request 来解决这个问题,建议您观看:
https://github.com/OpenAPITools/openapi-generator/pull/4407
在此期间,您可以尝试使用类似于 springdoc-openapi-data-rest 中可用的 @PageableAsQueryParam
注释来解决问题。也就是说,您可以在 Spring 控制器方法上使用 @Parameters 并在方法参数本身上使用 @Parameter(hidden = true)
来手动重新定义文档。
这很糟糕,但这是 Pull Request 通过之前的最佳解决方案。
对于您编写的方法,修复会相当简单,只需添加 @PageableAsQueryParam
和 @Parameter(hidden = true)
:
@PageableAsQueryParam
@SecuredMaster
@GetMapping(path = "/mitarbeiter")
@Operation(security = {@SecurityRequirement(name = "jwt")})
public Page<MitarbeiterListRow> getMitarbeiter(@Parameter(hidden = true) Pageable pageable, @RequestParam(defaultValue = "") String query) {
return mitarbeiterRepository.findAllByUsernameContainingIgnoreCaseOrEmailContainingIgnoreCase(pageable, query, query);
}
我的 spring 启动应用程序中有以下 Rest 函数
@SecuredMaster
@GetMapping(path = "/mitarbeiter")
@Operation(security = {@SecurityRequirement(name = "jwt")})
public Page<MitarbeiterListRow> getMitarbeiter(Pageable pageable, @RequestParam(defaultValue = "") String query) {
return mitarbeiterRepository.findAllByUsernameContainingIgnoreCaseOrEmailContainingIgnoreCase(pageable, query, query);
}
我使用 springdoc 生成 openapi3 yaml
// generate api docs
implementation 'org.springdoc:springdoc-openapi-ui:1.2.18'
implementation 'org.springdoc:springdoc-openapi-data-rest:1.2.18'
生成的 yaml 看起来像这样
然后我生成一个angular客户端
java -jar swagger-codegen-cli.jar generate -i http://localhost:8080/apidocs/v3/api-docs -l typescript-angular -o ../frontend/src/generated/swagger
生成的客户端如下所示
/**
*
*
* @param pageable
* @param query
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
public getMitarbeiter(pageable: Pageable, query?: string, observe?: 'body', reportProgress?: boolean): Observable<PageMitarbeiterListRow>;
public getMitarbeiter(pageable: Pageable, query?: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<PageMitarbeiterListRow>>;
public getMitarbeiter(pageable: Pageable, query?: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<PageMitarbeiterListRow>>;
public getMitarbeiter(pageable: Pageable, query?: string, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
if (pageable === null || pageable === undefined) {
throw new Error('Required parameter pageable was null or undefined when calling getMitarbeiter.');
}
let queryParameters = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()});
if (pageable !== undefined && pageable !== null) {
queryParameters = queryParameters.set('pageable', <any>pageable);
}
if (query !== undefined && query !== null) {
queryParameters = queryParameters.set('query', <any>query);
}
let headers = this.defaultHeaders;
// authentication (jwt) required
if (this.configuration.accessToken) {
const accessToken = typeof this.configuration.accessToken === 'function'
? this.configuration.accessToken()
: this.configuration.accessToken;
headers = headers.set('Authorization', 'Bearer ' + accessToken);
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'*/*'
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}
// to determine the Content-Type header
const consumes: string[] = [
];
return this.httpClient.get<PageMitarbeiterListRow>(`${this.basePath}/mitarbeiter`,
{
params: queryParameters,
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
}
);
}
当我使用生成的服务时,它会发出这样的请求:
但是当我使用 swagger 时 UI 它工作正常
为什么 swagger-ui 发出正确的请求而生成的 angular-client 却没有?
这是 typescript-angular 生成器的问题:
https://github.com/OpenAPITools/openapi-generator/issues/4404
已经创建了一个 Pull Request 来解决这个问题,建议您观看:
https://github.com/OpenAPITools/openapi-generator/pull/4407
在此期间,您可以尝试使用类似于 springdoc-openapi-data-rest 中可用的 @PageableAsQueryParam
注释来解决问题。也就是说,您可以在 Spring 控制器方法上使用 @Parameters 并在方法参数本身上使用 @Parameter(hidden = true)
来手动重新定义文档。
这很糟糕,但这是 Pull Request 通过之前的最佳解决方案。
对于您编写的方法,修复会相当简单,只需添加 @PageableAsQueryParam
和 @Parameter(hidden = true)
:
@PageableAsQueryParam
@SecuredMaster
@GetMapping(path = "/mitarbeiter")
@Operation(security = {@SecurityRequirement(name = "jwt")})
public Page<MitarbeiterListRow> getMitarbeiter(@Parameter(hidden = true) Pageable pageable, @RequestParam(defaultValue = "") String query) {
return mitarbeiterRepository.findAllByUsernameContainingIgnoreCaseOrEmailContainingIgnoreCase(pageable, query, query);
}