mirror of
https://github.com/gotson/komga.git
synced 2026-02-14 19:33:02 +01:00
feat(swagger): update to OpenAPI 3
migrate from Springfox to Springdoc
This commit is contained in:
parent
b900227c83
commit
c9de7c8074
6 changed files with 65 additions and 38 deletions
|
|
@ -51,9 +51,11 @@ dependencies {
|
|||
implementation("io.micrometer:micrometer-registry-influx")
|
||||
|
||||
run {
|
||||
val springfoxVersion = "2.9.2"
|
||||
implementation("io.springfox:springfox-swagger2:$springfoxVersion")
|
||||
implementation("io.springfox:springfox-swagger-ui:$springfoxVersion")
|
||||
val springdocVersion = "1.3.1"
|
||||
implementation("org.springdoc:springdoc-openapi-ui:$springdocVersion")
|
||||
implementation("org.springdoc:springdoc-openapi-data-rest:$springdocVersion")
|
||||
implementation("org.springdoc:springdoc-openapi-security:$springdocVersion")
|
||||
implementation("org.springdoc:springdoc-openapi-kotlin:$springdocVersion")
|
||||
}
|
||||
|
||||
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
|
||||
|
|
|
|||
|
|
@ -1,36 +1,34 @@
|
|||
package org.gotson.komga.infrastructure.swagger
|
||||
|
||||
import io.swagger.v3.oas.models.Components
|
||||
import io.swagger.v3.oas.models.ExternalDocumentation
|
||||
import io.swagger.v3.oas.models.OpenAPI
|
||||
import io.swagger.v3.oas.models.info.Info
|
||||
import io.swagger.v3.oas.models.info.License
|
||||
import io.swagger.v3.oas.models.security.SecurityScheme
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.core.Ordered
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
|
||||
import org.springframework.web.context.request.WebRequest
|
||||
import springfox.documentation.schema.AlternateTypeRules
|
||||
import springfox.documentation.spi.DocumentationType
|
||||
import springfox.documentation.spring.web.plugins.Docket
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2
|
||||
|
||||
@Configuration
|
||||
@EnableSwagger2
|
||||
class SwaggerConfiguration {
|
||||
|
||||
@Bean
|
||||
fun getDocket(): Docket =
|
||||
Docket(DocumentationType.SWAGGER_2)
|
||||
.ignoredParameterTypes(
|
||||
AuthenticationPrincipal::class.java,
|
||||
WebRequest::class.java
|
||||
)
|
||||
.alternateTypeRules(AlternateTypeRules.newRule(
|
||||
Pageable::class.java,
|
||||
PageableMixin::class.java,
|
||||
Ordered.HIGHEST_PRECEDENCE
|
||||
))
|
||||
fun openApi(): OpenAPI =
|
||||
OpenAPI()
|
||||
.info(Info()
|
||||
.title("Komga API")
|
||||
.version("v1.0")
|
||||
.description("""
|
||||
Komga offers 2 APIs: REST and OPDS.
|
||||
|
||||
private class PageableMixin {
|
||||
val page = 0
|
||||
val size = 20
|
||||
val sort = ""
|
||||
}
|
||||
Both APIs are secured using HTTP Basic Authentication.
|
||||
""".trimIndent())
|
||||
.license(License().name("MIT").url("https://github.com/gotson/komga/blob/master/LICENSE")))
|
||||
.externalDocs(ExternalDocumentation()
|
||||
.description("Komga documentation")
|
||||
.url("https://komga.org"))
|
||||
.components(Components()
|
||||
.addSecuritySchemes(
|
||||
"basicAuth",
|
||||
SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package org.gotson.komga.interfaces.rest
|
|||
import com.github.klinq.jpaspec.`in`
|
||||
import com.github.klinq.jpaspec.likeLower
|
||||
import com.github.klinq.jpaspec.toJoin
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import io.swagger.v3.oas.annotations.Parameter
|
||||
import mu.KotlinLogging
|
||||
import org.gotson.komga.application.service.AsyncOrchestrator
|
||||
import org.gotson.komga.application.service.BookLifecycle
|
||||
|
|
@ -21,6 +23,7 @@ import org.gotson.komga.interfaces.rest.dto.BookDto
|
|||
import org.gotson.komga.interfaces.rest.dto.BookMetadataUpdateDto
|
||||
import org.gotson.komga.interfaces.rest.dto.PageDto
|
||||
import org.gotson.komga.interfaces.rest.dto.toDto
|
||||
import org.springdoc.api.annotations.ParameterObject
|
||||
import org.springframework.core.io.FileSystemResource
|
||||
import org.springframework.data.domain.Page
|
||||
import org.springframework.data.domain.PageRequest
|
||||
|
|
@ -71,7 +74,7 @@ class BookController(
|
|||
@RequestParam(name = "search", required = false) searchTerm: String?,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: List<Long>?,
|
||||
@RequestParam(name = "media_status", required = false) mediaStatus: List<Media.Status>?,
|
||||
page: Pageable
|
||||
@ParameterObject page: Pageable
|
||||
): Page<BookDto> {
|
||||
val pageRequest = PageRequest.of(
|
||||
page.pageNumber,
|
||||
|
|
@ -115,10 +118,12 @@ class BookController(
|
|||
}
|
||||
|
||||
|
||||
@Operation(description = "Return newly added or updated books.")
|
||||
@GetMapping("api/v1/books/latest")
|
||||
@Parameter(name = "sort", hidden = true)
|
||||
fun getLatestSeries(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
page: Pageable
|
||||
@ParameterObject page: Pageable
|
||||
): Page<BookDto> {
|
||||
val pageRequest = PageRequest.of(
|
||||
page.pageNumber,
|
||||
|
|
@ -193,6 +198,7 @@ class BookController(
|
|||
} else throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
|
||||
@Operation(description = "Download the book file.")
|
||||
@GetMapping(value = [
|
||||
"api/v1/books/{bookId}/file",
|
||||
"api/v1/books/{bookId}/file/*",
|
||||
|
|
@ -348,6 +354,7 @@ class BookController(
|
|||
@PreAuthorize("hasRole('ADMIN')")
|
||||
fun updateMetadata(
|
||||
@PathVariable bookId: Long,
|
||||
@Parameter(description = "Metadata fields to update. Set a field to null to unset the metadata. You can omit fields you don't want to update.")
|
||||
@Valid @RequestBody newMetadata: BookMetadataUpdateDto
|
||||
): BookDto =
|
||||
bookRepository.findByIdOrNull(bookId)?.let { book ->
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package org.gotson.komga.interfaces.rest
|
|||
import com.github.klinq.jpaspec.`in`
|
||||
import com.github.klinq.jpaspec.likeLower
|
||||
import com.github.klinq.jpaspec.toJoin
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import io.swagger.v3.oas.annotations.Parameter
|
||||
import mu.KotlinLogging
|
||||
import org.gotson.komga.application.service.AsyncOrchestrator
|
||||
import org.gotson.komga.domain.model.Library
|
||||
|
|
@ -16,6 +18,7 @@ import org.gotson.komga.interfaces.rest.dto.BookDto
|
|||
import org.gotson.komga.interfaces.rest.dto.SeriesDto
|
||||
import org.gotson.komga.interfaces.rest.dto.SeriesMetadataUpdateDto
|
||||
import org.gotson.komga.interfaces.rest.dto.toDto
|
||||
import org.springdoc.api.annotations.ParameterObject
|
||||
import org.springframework.data.domain.Page
|
||||
import org.springframework.data.domain.PageRequest
|
||||
import org.springframework.data.domain.Pageable
|
||||
|
|
@ -57,7 +60,7 @@ class SeriesController(
|
|||
@RequestParam(name = "search", required = false) searchTerm: String?,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: List<Long>?,
|
||||
@RequestParam(name = "status", required = false) metadataStatus: List<SeriesMetadata.Status>?,
|
||||
page: Pageable
|
||||
@ParameterObject page: Pageable
|
||||
): Page<SeriesDto> {
|
||||
val pageRequest = PageRequest.of(
|
||||
page.pageNumber,
|
||||
|
|
@ -100,11 +103,12 @@ class SeriesController(
|
|||
}.map { it.toDto(includeUrl = principal.user.isAdmin()) }
|
||||
}
|
||||
|
||||
// all updated series, whether newly added or updated
|
||||
@Operation(description = "Return recently added or updated series.")
|
||||
@GetMapping("/latest")
|
||||
@Parameter(name = "sort", hidden = true)
|
||||
fun getLatestSeries(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
page: Pageable
|
||||
@ParameterObject page: Pageable
|
||||
): Page<SeriesDto> {
|
||||
val pageRequest = PageRequest.of(
|
||||
page.pageNumber,
|
||||
|
|
@ -119,11 +123,12 @@ class SeriesController(
|
|||
}.map { it.toDto(includeUrl = principal.user.isAdmin()) }
|
||||
}
|
||||
|
||||
// new series only, doesn't contain existing updated series
|
||||
@Operation(description = "Return newly added series.")
|
||||
@GetMapping("/new")
|
||||
@Parameter(name = "sort", hidden = true)
|
||||
fun getNewSeries(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
page: Pageable
|
||||
@ParameterObject page: Pageable
|
||||
): Page<SeriesDto> {
|
||||
val pageRequest = PageRequest.of(
|
||||
page.pageNumber,
|
||||
|
|
@ -138,11 +143,12 @@ class SeriesController(
|
|||
}.map { it.toDto(includeUrl = principal.user.isAdmin()) }
|
||||
}
|
||||
|
||||
// updated series only, doesn't contain new series
|
||||
@Operation(description = "Return recently updated series, but not newly added ones.")
|
||||
@GetMapping("/updated")
|
||||
@Parameter(name = "sort", hidden = true)
|
||||
fun getUpdatedSeries(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
page: Pageable
|
||||
@ParameterObject page: Pageable
|
||||
): Page<SeriesDto> {
|
||||
val pageRequest = PageRequest.of(
|
||||
page.pageNumber,
|
||||
|
|
@ -185,7 +191,7 @@ class SeriesController(
|
|||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@PathVariable(name = "seriesId") id: Long,
|
||||
@RequestParam(name = "media_status", required = false) mediaStatus: List<Media.Status>?,
|
||||
page: Pageable
|
||||
@ParameterObject page: Pageable
|
||||
): Page<BookDto> {
|
||||
seriesRepository.findByIdOrNull(id)?.let {
|
||||
if (!principal.user.canAccessSeries(it)) throw ResponseStatusException(HttpStatus.UNAUTHORIZED)
|
||||
|
|
@ -234,6 +240,7 @@ class SeriesController(
|
|||
@PreAuthorize("hasRole('ADMIN')")
|
||||
fun updateMetadata(
|
||||
@PathVariable seriesId: Long,
|
||||
@Parameter(description = "Metadata fields to update. Set a field to null to unset the metadata. You can omit fields you don't want to update.")
|
||||
@Valid @RequestBody newMetadata: SeriesMetadataUpdateDto
|
||||
): SeriesDto =
|
||||
seriesRepository.findByIdOrNull(seriesId)?.let { series ->
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ management.metrics.export.influx:
|
|||
# enabled: true
|
||||
uri: http://localhost:8086
|
||||
|
||||
springdoc:
|
||||
cache:
|
||||
disabled: true
|
||||
|
||||
#server:
|
||||
# servlet:
|
||||
# context-path: /komga
|
||||
|
|
|
|||
|
|
@ -53,3 +53,12 @@ management:
|
|||
export:
|
||||
influx:
|
||||
enabled: false
|
||||
springdoc:
|
||||
group-configs:
|
||||
- group: REST API
|
||||
paths-to-match: /api/**
|
||||
- group: OPDS
|
||||
paths-to-match: /opds/**
|
||||
swagger-ui:
|
||||
groups-order: desc
|
||||
operations-sorter: alpha
|
||||
|
|
|
|||
Loading…
Reference in a new issue