Skip to content

Commit

Permalink
GH-211 Support response headers (Resolve #211)
Browse files Browse the repository at this point in the history
  • Loading branch information
dzikoysk committed Jan 29, 2024
1 parent 5e2b091 commit 0d81c03
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.fasterxml.jackson.databind.node.TextNode;
import io.javalin.Javalin;
import io.javalin.http.Context;
import io.javalin.http.CreatedResponse;
import io.javalin.http.Handler;
import io.javalin.openapi.ApiKeyAuth;
import io.javalin.openapi.BasicAuth;
Expand Down Expand Up @@ -39,12 +38,9 @@
import io.javalin.openapi.OpenID;
import io.javalin.openapi.Security;
import io.javalin.openapi.Visibility;
import io.javalin.openapi.plugin.OpenApiPluginConfiguration;
import io.javalin.openapi.plugin.OpenApiPlugin;
import io.javalin.openapi.plugin.SecurityComponentConfiguration;
import io.javalin.openapi.plugin.redoc.ReDocConfiguration;
import io.javalin.openapi.plugin.redoc.ReDocPlugin;
import io.javalin.openapi.plugin.swagger.SwaggerConfiguration;
import io.javalin.openapi.plugin.swagger.SwaggerPlugin;
import lombok.Data;
import org.bson.types.ObjectId;
Expand Down Expand Up @@ -187,7 +183,10 @@ public static void main(String[] args) {
@OpenApiResponse(
status = "400",
description = "Error message related to the invalid command format (0 < command length < " + 10 + ")",
content = @OpenApiContent(from = EntityDto[].class)
content = @OpenApiContent(from = EntityDto[].class),
headers = {
@OpenApiParam(name = "X-Error-Message", description = "Error message", type = String.class)
}
),
@OpenApiResponse(status = "401", description = "Error message related to the unauthorized access", content = {
@OpenApiContent(from = EntityDto[].class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import io.javalin.openapi.OpenApiResponse
import io.javalin.openapi.OpenApis
import io.javalin.openapi.experimental.ClassDefinition
import io.javalin.openapi.experimental.StructureType.ARRAY
import io.javalin.openapi.experimental.processor.shared.addIfNotEmpty
import io.javalin.openapi.experimental.processor.shared.addString
import io.javalin.openapi.experimental.processor.shared.computeIfAbsent
import io.javalin.openapi.experimental.processor.shared.getTypeMirror
Expand Down Expand Up @@ -146,10 +147,9 @@ internal class OpenApiGenerator {
)

parameterAnnotations.forEach { (parameterType, annotations) ->
annotations
.forEach { parameterAnnotation ->
parameters.add(fromParameter(parameterType, parameterAnnotation))
}
annotations.forEach { parameterAnnotation ->
parameters.add(fromParameter(parameterType, parameterAnnotation, explicit = true))
}
}

operation.add("parameters", parameters)
Expand Down Expand Up @@ -262,11 +262,7 @@ internal class OpenApiGenerator {
val requestBody = JsonObject()
requestBody.addString("description", requestBodyAnnotation.description)
requestBody.addContent(openApiElement, requestBodyAnnotation.content)

if (requestBody.size() > 0) {
add("requestBody", requestBody)
}

addIfNotEmpty("requestBody", requestBody)
requestBody.addProperty("required", requestBodyAnnotation.required)
}

Expand All @@ -278,13 +274,19 @@ internal class OpenApiGenerator {

val description = responseAnnotation.description
.takeIf { it != NULL_STRING }
?: responseAnnotation.status
?: responseAnnotation
.status
.toIntOrNull()
?.let { HttpStatus.forStatus(it) }?.message
?.let { HttpStatus.forStatus(it) }
?.message

response.addString("description", description)
response.addContent(openApiElement, responseAnnotation.content)
responses.add(responseAnnotation.status, response)

val headers = JsonObject()
responseAnnotation.headers.forEach { headers.add(it.name, fromParameter(HEADER, it, explicit = false)) }
response.addIfNotEmpty("headers", headers)
}

add("responses", responses)
Expand All @@ -300,21 +302,35 @@ internal class OpenApiGenerator {

// Parameter
// https://swagger.io/specification/#parameter-object
private fun fromParameter(`in`: In, parameterInstance: OpenApiParam?): JsonObject {
private fun fromParameter(`in`: In, parameterInstance: OpenApiParam, explicit: Boolean): JsonObject {
val parameter = JsonObject()
parameter.addString("name", parameterInstance!!.name)
parameter.addString("in", `in`.identifier)

if (explicit) {
parameter.addString("name", parameterInstance.name)
parameter.addString("in", `in`.identifier)
}

parameter.addString("description", parameterInstance.description)
parameter.addProperty("required", parameterInstance.required)
parameter.addProperty("deprecated", parameterInstance.deprecated)
parameter.addProperty("allowEmptyValue", parameterInstance.allowEmptyValue)

if (explicit || parameterInstance.required) {
parameter.addProperty("required", parameterInstance.required)
}

if (explicit || parameterInstance.deprecated) {
parameter.addProperty("deprecated", parameterInstance.deprecated)
}

if (explicit || parameterInstance.allowEmptyValue) {
parameter.addProperty("allowEmptyValue", parameterInstance.allowEmptyValue)
}

val schema = createTypeDescriptionWithReferences(parameterInstance.getTypeMirror { type })
parameterInstance.example
.takeIf { it.isNotEmpty() }
.let { schema.addProperty("example", it) }
parameter.add("schema", schema)

if (parameterInstance.example.isNotEmpty()) {
schema.addProperty("example", parameterInstance.example)
}

parameter.add("schema", schema)
return parameter
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ annotation class OpenApis(
annotation class OpenApiResponse(
val status: String,
val content: Array<OpenApiContent> = [],
val description: String = NULL_STRING
val description: String = NULL_STRING,
val headers: Array<OpenApiParam> = [],
)

@Target()
Expand All @@ -108,7 +109,6 @@ annotation class OpenApiParam(
val deprecated: Boolean = false,
val required: Boolean = false,
val allowEmptyValue: Boolean = false,
val isRepeatable: Boolean = false,
val example: String = ""
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ fun JsonObject.addString(key: String, value: String?): JsonObject = also {
}
}

fun JsonObject.addIfNotEmpty(key: String, value: JsonObject): JsonObject = also {
if (value.size() > 0) {
add(key, value)
}
}

fun createJsonObjectOf(key: String, value: String): JsonObject {
val jsonObject = JsonObject()
jsonObject.addProperty(key, value)
Expand Down

0 comments on commit 0d81c03

Please sign in to comment.