From 2b18af2b2d3e480ab095dad1d9ee7a9e0134ca83 Mon Sep 17 00:00:00 2001 From: Raymond Yang Date: Thu, 18 May 2023 09:52:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5swagger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 5 + src/main/kotlin/com/ray650128/Application.kt | 13 +- .../com/ray650128/plugins/SwaggerRouting.kt | 12 + .../com/ray650128/plugins/UserRouting.kt | 4 +- src/main/resources/openapi/documentation.yaml | 570 ++++++++++++++++++ 5 files changed, 600 insertions(+), 4 deletions(-) create mode 100644 src/main/kotlin/com/ray650128/plugins/SwaggerRouting.kt create mode 100644 src/main/resources/openapi/documentation.yaml diff --git a/build.gradle.kts b/build.gradle.kts index 8cccf44..0a3a3b7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,7 @@ val ktor_version: String by project val kotlin_version: String by project val logback_version: String by project val kmongo_version: String by project +val swagger_codegen_version: String by project plugins { kotlin("jvm") version "1.8.21" @@ -24,6 +25,9 @@ repositories { dependencies { implementation("io.ktor:ktor-server-core-jvm:$ktor_version") + implementation("io.ktor:ktor-server-swagger:$ktor_version") + implementation("io.ktor:ktor-server-openapi:$ktor_version") + implementation("io.ktor:ktor-server-cors:$ktor_version") implementation("io.ktor:ktor-server-content-negotiation-jvm:$ktor_version") implementation("io.ktor:ktor-serialization-kotlinx-json-jvm:$ktor_version") implementation("io.ktor:ktor-server-netty-jvm:$ktor_version") @@ -35,4 +39,5 @@ dependencies { implementation("io.ktor:ktor-server-auth-jvm:$ktor_version") implementation("io.ktor:ktor-server-auth-jwt-jvm:$ktor_version") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0") + implementation("io.swagger.codegen.v3:swagger-codegen-generators:1.0.39") } \ No newline at end of file diff --git a/src/main/kotlin/com/ray650128/Application.kt b/src/main/kotlin/com/ray650128/Application.kt index 2ef9b76..db85730 100644 --- a/src/main/kotlin/com/ray650128/Application.kt +++ b/src/main/kotlin/com/ray650128/Application.kt @@ -1,10 +1,11 @@ package com.ray650128 -import com.ray650128.model.pojo.User -import com.ray650128.plugins.configureUserRouting import com.ray650128.plugins.configureArMaterialRouting import com.ray650128.plugins.configureArModelRouting +import com.ray650128.plugins.configureSwaggerRouting +import com.ray650128.plugins.configureUserRouting import com.ray650128.service.UserService +import io.ktor.http.* import io.ktor.serialization.kotlinx.json.* import io.ktor.server.application.* import io.ktor.server.auth.* @@ -12,6 +13,8 @@ import io.ktor.server.auth.jwt.* import io.ktor.server.engine.* import io.ktor.server.netty.* import io.ktor.server.plugins.contentnegotiation.* +import io.ktor.server.plugins.cors.routing.* +import io.swagger.codegen.v3.generators.html.* import kotlinx.serialization.json.Json import org.litote.kmongo.id.serialization.IdKotlinXSerializationModule @@ -37,8 +40,14 @@ fun main() { } } } + + install(CORS) { + anyHost() + allowHeader(HttpHeaders.ContentType) + } configureUserRouting() configureArMaterialRouting() configureArModelRouting() + configureSwaggerRouting() }.start(wait = true) } diff --git a/src/main/kotlin/com/ray650128/plugins/SwaggerRouting.kt b/src/main/kotlin/com/ray650128/plugins/SwaggerRouting.kt new file mode 100644 index 0000000..534e617 --- /dev/null +++ b/src/main/kotlin/com/ray650128/plugins/SwaggerRouting.kt @@ -0,0 +1,12 @@ +package com.ray650128.plugins + +import io.ktor.server.application.* +import io.ktor.server.plugins.swagger.* +import io.ktor.server.routing.* + +fun Application.configureSwaggerRouting() { + + routing { + swaggerUI(path = "swagger", swaggerFile = "openapi/documentation.yaml") + } +} diff --git a/src/main/kotlin/com/ray650128/plugins/UserRouting.kt b/src/main/kotlin/com/ray650128/plugins/UserRouting.kt index 82f89b7..8a1ae2c 100644 --- a/src/main/kotlin/com/ray650128/plugins/UserRouting.kt +++ b/src/main/kotlin/com/ray650128/plugins/UserRouting.kt @@ -73,7 +73,7 @@ fun Application.configureUserRouting() { } } - get { + /*get { val peopleList = service.findAll() call.respond(peopleList) } @@ -110,7 +110,7 @@ fun Application.configureUserRouting() { } else { call.respond(HttpStatusCode.NotFound, ErrorResponse.NOT_FOUND_RESPONSE) } - } + }*/ } } } diff --git a/src/main/resources/openapi/documentation.yaml b/src/main/resources/openapi/documentation.yaml new file mode 100644 index 0000000..6d714b1 --- /dev/null +++ b/src/main/resources/openapi/documentation.yaml @@ -0,0 +1,570 @@ +openapi: "3.0.3" +info: + title: "KtorMongoTest API" + description: "KtorMongoTest API" + version: "1.0.0" +servers: +- url: "https://KtorMongoTest" +paths: + /api/v1/models: + get: + description: "" + responses: + "401": + description: "Unauthorized" + content: + '*/*': + schema: + type: "object" + "200": + description: "OK" + content: + '*/*': + schema: + $ref: "#/components/schemas/Object" + /api/v1/models/{id}: + delete: + description: "" + parameters: + - name: "id" + in: "path" + required: true + schema: + type: "string" + responses: + "401": + description: "Unauthorized" + content: + '*/*': + schema: + $ref: "#/components/schemas/ErrorResponse" + "200": + description: "OK" + content: + '*/*': + schema: + $ref: "#/components/schemas/Object" + put: + description: "" + parameters: + - name: "id" + in: "path" + required: true + schema: + type: "string" + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/ArModel" + required: true + responses: + "401": + description: "Unauthorized" + content: + '*/*': + schema: + $ref: "#/components/schemas/ErrorResponse" + "200": + description: "OK" + content: + '*/*': + schema: + $ref: "#/components/schemas/Object" + /api/v1/models/create: + post: + description: "" + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/ArModel" + required: true + responses: + "401": + description: "Unauthorized" + content: + '*/*': + schema: + $ref: "#/components/schemas/ErrorResponse" + "200": + description: "OK" + content: + '*/*': + schema: + $ref: "#/components/schemas/Object" + "400": + description: "Bad Request" + content: + '*/*': + schema: + $ref: "#/components/schemas/ErrorResponse" + /api/v1/login: + post: + description: "" + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/User" + required: true + responses: + "200": + description: "OK" + content: + '*/*': + schema: + $ref: "#/components/schemas/Object" + "400": + description: "Bad Request" + content: + '*/*': + schema: + $ref: "#/components/schemas/ErrorResponse" + /api/v1/logout: + post: + description: "" + responses: + "401": + description: "Unauthorized" + content: + '*/*': + schema: + type: "object" + "200": + description: "OK" + content: + '*/*': + schema: + $ref: "#/components/schemas/Object" + /api/v1/register: + post: + description: "" + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/User" + required: true + responses: + "400": + description: "Bad Request" + content: + '*/*': + schema: + type: "object" + headers: + My-User-Id-Header: + required: true + schema: + type: "string" + "201": + description: "Created" + content: + '*/*': + schema: + $ref: "#/components/schemas/Object" + headers: + My-User-Id-Header: + required: true + schema: + type: "string" + /api/v1/materials: + get: + description: "" + responses: + "401": + description: "Unauthorized" + content: + '*/*': + schema: + $ref: "#/components/schemas/ErrorResponse" + "200": + description: "OK" + content: + '*/*': + schema: + $ref: "#/components/schemas/Object" + /api/v1/materials/{id}: + delete: + description: "" + parameters: + - name: "id" + in: "path" + required: true + schema: + type: "string" + responses: + "401": + description: "Unauthorized" + content: + '*/*': + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: "Not Found" + content: + '*/*': + schema: + $ref: "#/components/schemas/ErrorResponse" + "200": + description: "OK" + content: + '*/*': + schema: + $ref: "#/components/schemas/Object" + put: + description: "" + parameters: + - name: "id" + in: "path" + required: true + schema: + type: "string" + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/Material" + required: true + responses: + "401": + description: "Unauthorized" + content: + '*/*': + schema: + $ref: "#/components/schemas/ErrorResponse" + "404": + description: "Not Found" + content: + '*/*': + schema: + $ref: "#/components/schemas/ErrorResponse" + "200": + description: "OK" + content: + '*/*': + schema: + $ref: "#/components/schemas/Object" + /api/v1/materials/upload: + post: + description: "" + responses: + "401": + description: "Unauthorized" + content: + '*/*': + schema: + $ref: "#/components/schemas/ErrorResponse" + "200": + description: "OK" + content: + '*/*': + schema: + $ref: "#/components/schemas/Object" + "400": + description: "Bad Request" + content: + '*/*': + schema: + $ref: "#/components/schemas/ErrorResponse" + /upload/{name}: + get: + description: "" + parameters: + - name: "name" + in: "path" + required: true + schema: + type: "string" + responses: + "404": + description: "Not Found" + content: + '*/*': + schema: + type: "object" + "200": + description: "OK
A file response" + content: + application/*: + schema: + type: "object" + format: "binary" +components: + schemas: + ErrorResponse: + type: "object" + properties: + message: + type: "string" + Object: + type: "object" + properties: {} + User: + type: "object" + properties: + _id: + $ref: "#/components/schemas/User" + account: + type: "string" + password: + type: "string" + name: + type: "string" + token: + type: "string" + createAt: + type: "integer" + format: "int64" + updatedAt: + type: "integer" + format: "int64" + Float3: + type: "object" + properties: + x: + type: "number" + format: "float" + "y": + type: "number" + format: "float" + z: + type: "number" + format: "float" + Material: + type: "object" + properties: + _id: + $ref: "#/components/schemas/Material" + ownerId: + $ref: "#/components/schemas/User" + name: + type: "string" + path: + type: "string" + contentType: + type: "string" + fileTag: + type: "string" + createAt: + type: "integer" + format: "int64" + updatedAt: + type: "integer" + format: "int64" + Color: + type: "object" + properties: + r: + type: "number" + format: "float" + g: + type: "number" + format: "float" + b: + type: "number" + format: "float" + a: + type: "number" + format: "float" + ModelParams: + type: "object" + properties: + availableRange: + type: "number" + format: "float" + width: + type: "number" + format: "float" + height: + type: "number" + format: "float" + depth: + type: "number" + format: "float" + radius: + type: "number" + format: "float" + modelAnimSpeed: + type: "number" + format: "float" + modelStartFrame: + type: "number" + format: "float" + modelEndFrame: + type: "number" + format: "float" + modelFPS: + type: "number" + format: "float" + multiplyNumber: + type: "integer" + format: "int32" + multiplyRadius: + type: "number" + format: "float" + multiplyRange: + type: "number" + format: "float" + hueAngle: + type: "number" + format: "float" + hueRange: + type: "number" + format: "float" + saturation: + type: "number" + format: "float" + videoThumbnail: + type: "string" + lightIntensity: + type: "number" + format: "float" + color: + $ref: "#/components/schemas/Color" + levelCount: + type: "integer" + format: "int32" + levelBorders: + type: "number" + format: "float" + levelAngles: + type: "number" + format: "float" + planeCount: + type: "integer" + format: "int32" + planeBorder: + type: "number" + format: "float" + speed: + type: "number" + format: "float" + signIcon: + type: "string" + signName: + type: "string" + signTextColor: + $ref: "#/components/schemas/Color" + ModelData: + type: "object" + properties: + type: + type: "integer" + format: "int32" + material: + $ref: "#/components/schemas/Material" + params: + $ref: "#/components/schemas/ModelParams" + ModelAction: + type: "object" + properties: + actionType: + type: "integer" + format: "int32" + duration: + type: "number" + format: "float" + translation: + $ref: "#/components/schemas/Float3" + rotation: + $ref: "#/components/schemas/Float3" + scale: + $ref: "#/components/schemas/Float3" + alpha: + type: "number" + format: "float" + webUrl: + type: "string" + speed: + type: "number" + format: "float" + startFrame: + type: "number" + format: "float" + endFrame: + type: "number" + format: "float" + fps: + type: "number" + format: "float" + repeatCount: + type: "integer" + format: "int32" + squareMoveWidth: + type: "number" + format: "float" + squareMoveHeight: + type: "number" + format: "float" + squareMoveTime: + type: "number" + format: "float" + squareMoveRotationTime: + type: "number" + format: "float" + clockwise: + type: "boolean" + roundMoveRadius: + type: "number" + format: "float" + roundMoveStartAngle: + type: "number" + format: "float" + roundMoveEndAngel: + type: "number" + format: "float" + resolution: + type: "number" + format: "float" + moveToFaceDistance: + type: "number" + format: "float" + autoReturnDelay: + type: "number" + format: "float" + vibrationTime: + type: "integer" + format: "int32" + targetId: + type: "integer" + format: "int32" + groupNumber: + type: "integer" + format: "int32" + ModelEvent: + type: "object" + properties: + eventType: + type: "integer" + format: "int32" + actions: + $ref: "#/components/schemas/ModelAction" + ArModel: + type: "object" + properties: + _id: + $ref: "#/components/schemas/ArModel" + ownerId: + $ref: "#/components/schemas/User" + name: + type: "string" + position: + $ref: "#/components/schemas/Float3" + rotation: + $ref: "#/components/schemas/Float3" + scale: + $ref: "#/components/schemas/Float3" + modelData: + $ref: "#/components/schemas/ModelData" + events: + $ref: "#/components/schemas/ModelEvent" + childEvents: + type: "string" + createAt: + type: "integer" + format: "int64" + updatedAt: + type: "integer" + format: "int64" \ No newline at end of file