fix: References for for protobuf objects (#466)

This commit is contained in:
Jasper van Gelder
2023-06-05 22:12:31 +02:00
committed by GitHub
parent 592c116c3b
commit 68bae4918e
9 changed files with 709 additions and 10 deletions

View File

@ -6,6 +6,8 @@
### Changed ### Changed
- Components definitions were not in the proper schema section. Prefixed the path with component slug in `protobuf java converter`.
### Remove ### Remove
--- ---

View File

@ -8,7 +8,7 @@ import kotlin.reflect.KType
object Helpers { object Helpers {
private const val COMPONENT_SLUG = "#/components/schemas" const val COMPONENT_SLUG = "#/components/schemas"
fun KType.getSlug(enrichment: Enrichment? = null) = when (enrichment) { fun KType.getSlug(enrichment: Enrichment? = null) = when (enrichment) {
is TypeEnrichment<*> -> getEnrichedSlug(enrichment) is TypeEnrichment<*> -> getEnrichedSlug(enrichment)

View File

@ -9,6 +9,7 @@ import io.bkbn.kompendium.json.schema.definition.MapDefinition
import io.bkbn.kompendium.json.schema.definition.NullableDefinition import io.bkbn.kompendium.json.schema.definition.NullableDefinition
import io.bkbn.kompendium.json.schema.definition.ReferenceDefinition import io.bkbn.kompendium.json.schema.definition.ReferenceDefinition
import io.bkbn.kompendium.json.schema.definition.TypeDefinition import io.bkbn.kompendium.json.schema.definition.TypeDefinition
import io.bkbn.kompendium.json.schema.util.Helpers
import kotlin.reflect.KType import kotlin.reflect.KType
import kotlin.reflect.full.createType import kotlin.reflect.full.createType
@ -150,7 +151,7 @@ fun fromTypeToSchema(
type = "string", type = "string",
enum = javaProtoField.enumType.values.map { it.name }.toSet() enum = javaProtoField.enumType.values.map { it.name }.toSet()
) )
ReferenceDefinition(javaProtoField.enumType.name) ReferenceDefinition("${Helpers.COMPONENT_SLUG}/${javaProtoField.enumType.name}")
} }
Descriptors.FieldDescriptor.JavaType.MESSAGE -> { Descriptors.FieldDescriptor.JavaType.MESSAGE -> {
// Traverse through possible nested messages // Traverse through possible nested messages
@ -160,7 +161,7 @@ fun fromTypeToSchema(
it.jsonName to fromNestedTypeToSchema(it, cache) it.jsonName to fromNestedTypeToSchema(it, cache)
}.toMap() }.toMap()
) )
ReferenceDefinition(javaProtoField.messageType.name) ReferenceDefinition("${Helpers.COMPONENT_SLUG}/${javaProtoField.messageType.name}")
} }
null -> NullableDefinition() null -> NullableDefinition()
} }

View File

@ -2,17 +2,21 @@ package io.bkbn.kompendium.protobufjavaconverter.converters
import com.google.protobuf.Descriptors import com.google.protobuf.Descriptors
import com.google.protobuf.GeneratedMessageV3 import com.google.protobuf.GeneratedMessageV3
import io.bkbn.kompendium.core.fixtures.TestHelpers.openApiTestAllSerializers
import io.bkbn.kompendium.core.metadata.PostInfo
import io.bkbn.kompendium.core.plugin.NotarizedRoute
import io.bkbn.kompendium.json.schema.definition.ArrayDefinition import io.bkbn.kompendium.json.schema.definition.ArrayDefinition
import io.bkbn.kompendium.json.schema.definition.EnumDefinition import io.bkbn.kompendium.json.schema.definition.EnumDefinition
import io.bkbn.kompendium.json.schema.definition.JsonSchema import io.bkbn.kompendium.json.schema.definition.JsonSchema
import io.bkbn.kompendium.json.schema.definition.MapDefinition import io.bkbn.kompendium.json.schema.definition.MapDefinition
import io.bkbn.kompendium.json.schema.definition.ReferenceDefinition import io.bkbn.kompendium.json.schema.definition.ReferenceDefinition
import io.bkbn.kompendium.json.schema.definition.TypeDefinition import io.bkbn.kompendium.json.schema.definition.TypeDefinition
import io.bkbn.kompendium.json.schema.util.Helpers
import io.bkbn.kompendium.protobufjavaconverter.Corpus import io.bkbn.kompendium.protobufjavaconverter.Corpus
import io.bkbn.kompendium.protobufjavaconverter.DoubleNestedMessage import io.bkbn.kompendium.protobufjavaconverter.DoubleNestedMessage
import io.bkbn.kompendium.protobufjavaconverter.NestedMapMessage
import io.bkbn.kompendium.protobufjavaconverter.EnumMessage import io.bkbn.kompendium.protobufjavaconverter.EnumMessage
import io.bkbn.kompendium.protobufjavaconverter.GoogleTypes import io.bkbn.kompendium.protobufjavaconverter.GoogleTypes
import io.bkbn.kompendium.protobufjavaconverter.NestedMapMessage
import io.bkbn.kompendium.protobufjavaconverter.NestedMessage import io.bkbn.kompendium.protobufjavaconverter.NestedMessage
import io.bkbn.kompendium.protobufjavaconverter.RepeatedEnumMessage import io.bkbn.kompendium.protobufjavaconverter.RepeatedEnumMessage
import io.bkbn.kompendium.protobufjavaconverter.RepeatedMessage import io.bkbn.kompendium.protobufjavaconverter.RepeatedMessage
@ -23,10 +27,15 @@ import io.kotest.matchers.maps.shouldContainExactly
import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldBe
import io.kotest.matchers.types.shouldBeTypeOf import io.kotest.matchers.types.shouldBeTypeOf
import io.kotest.matchers.types.shouldNotBeTypeOf import io.kotest.matchers.types.shouldNotBeTypeOf
import io.ktor.http.HttpStatusCode
import io.ktor.server.application.install
import io.ktor.server.routing.Route
import kotlin.reflect.KType import kotlin.reflect.KType
import kotlin.reflect.full.createType import kotlin.reflect.full.createType
class FieldDescriptiorConvertersKtTest : DescribeSpec({ class FieldDescriptiorConvertersKtTest : DescribeSpec({
val componentSlug = Helpers.COMPONENT_SLUG
describe("fromTypeToSchemaTests") { describe("fromTypeToSchemaTests") {
val simpleMessageDescriptor = SimpleTestMessage.getDescriptor() val simpleMessageDescriptor = SimpleTestMessage.getDescriptor()
it("java int field should return TypeDefinition INT") { it("java int field should return TypeDefinition INT") {
@ -77,7 +86,7 @@ class FieldDescriptiorConvertersKtTest : DescribeSpec({
val message = NestedMessage.getDescriptor() val message = NestedMessage.getDescriptor()
val result = fromNestedTypeToSchema(message.findFieldByName("nested_field")) val result = fromNestedTypeToSchema(message.findFieldByName("nested_field"))
result.shouldBeTypeOf<ReferenceDefinition>() result.shouldBeTypeOf<ReferenceDefinition>()
result.`$ref`.shouldBe(message.findFieldByName("nested_field").messageType.name) result.`$ref`.shouldBe("${Helpers.COMPONENT_SLUG}/${message.findFieldByName("nested_field").messageType.name}")
} }
it("Repeated message should return ArrayDefinition") { it("Repeated message should return ArrayDefinition") {
@ -85,7 +94,7 @@ class FieldDescriptiorConvertersKtTest : DescribeSpec({
val result = fromNestedTypeToSchema(message.findFieldByName("repeated_field")) val result = fromNestedTypeToSchema(message.findFieldByName("repeated_field"))
result.shouldBeTypeOf<ArrayDefinition>() result.shouldBeTypeOf<ArrayDefinition>()
result.items.shouldBeTypeOf<ReferenceDefinition>() result.items.shouldBeTypeOf<ReferenceDefinition>()
(result.items as ReferenceDefinition).`$ref`.shouldBe(SimpleTestMessage.getDescriptor().name) (result.items as ReferenceDefinition).`$ref`.shouldBe("$componentSlug/${SimpleTestMessage.getDescriptor().name}")
} }
it("Repeated enum message should return ArrayDefinition") { it("Repeated enum message should return ArrayDefinition") {
@ -93,7 +102,7 @@ class FieldDescriptiorConvertersKtTest : DescribeSpec({
val result: JsonSchema = fromNestedTypeToSchema(message.findFieldByName("repeated_field")) val result: JsonSchema = fromNestedTypeToSchema(message.findFieldByName("repeated_field"))
result.shouldBeTypeOf<ArrayDefinition>() result.shouldBeTypeOf<ArrayDefinition>()
result.items.shouldBeTypeOf<ReferenceDefinition>() result.items.shouldBeTypeOf<ReferenceDefinition>()
(result.items as ReferenceDefinition).`$ref`.shouldBe(Corpus.getDescriptor().name) (result.items as ReferenceDefinition).`$ref`.shouldBe("$componentSlug/${Corpus.getDescriptor().name}")
} }
it("SimpleMapMessage message should return MapDefinition") { it("SimpleMapMessage message should return MapDefinition") {
@ -169,7 +178,7 @@ class FieldDescriptiorConvertersKtTest : DescribeSpec({
// Our nested field should be a reference // Our nested field should be a reference
result.shouldBeTypeOf<ReferenceDefinition>() result.shouldBeTypeOf<ReferenceDefinition>()
// Our nested field should be a reference to simplemessage // Our nested field should be a reference to simplemessage
result.`$ref`.shouldBe(SimpleTestMessage.getDescriptor().name) result.`$ref`.shouldBe("$componentSlug/${SimpleTestMessage.getDescriptor().name}")
} }
it("Double nested message to schema") { it("Double nested message to schema") {
@ -201,11 +210,11 @@ class FieldDescriptiorConvertersKtTest : DescribeSpec({
// Our nested field should be a reference // Our nested field should be a reference
result.shouldBeTypeOf<ReferenceDefinition>() result.shouldBeTypeOf<ReferenceDefinition>()
// it should be a reference to our nested message // it should be a reference to our nested message
result.`$ref`.shouldBe(NestedMessage.getDescriptor().name) result.`$ref`.shouldBe("$componentSlug/${NestedMessage.getDescriptor().name}")
val nestedResult = (resultSchema[NestedMessage::class.createType()] as TypeDefinition).properties!!["nestedField"] val nestedResult = (resultSchema[NestedMessage::class.createType()] as TypeDefinition).properties!!["nestedField"]
nestedResult.shouldBeTypeOf<ReferenceDefinition>() nestedResult.shouldBeTypeOf<ReferenceDefinition>()
// Our nested message reference should be pointing to simpleTest message // Our nested message reference should be pointing to simpleTest message
nestedResult.`$ref`.shouldBe(SimpleTestMessage.getDescriptor().name) nestedResult.`$ref`.shouldBe("$componentSlug/${SimpleTestMessage.getDescriptor().name}")
// last but not least we should have definition for our SimpleTest message which is not a reference // last but not least we should have definition for our SimpleTest message which is not a reference
(resultSchema[SimpleTestMessage::class.createType()] as TypeDefinition).shouldNotBeTypeOf<ReferenceDefinition>() (resultSchema[SimpleTestMessage::class.createType()] as TypeDefinition).shouldNotBeTypeOf<ReferenceDefinition>()
} }
@ -235,6 +244,39 @@ class FieldDescriptiorConvertersKtTest : DescribeSpec({
testMessageBasics(message) testMessageBasics(message)
} }
} }
describe("Test spec generation") {
it("Generates simple message references") {
openApiTestAllSerializers(
"T0001__simpletestmessage_post.json",
testMessageBasics(SimpleTestMessage.getDefaultInstance())
) { testRoute<SimpleTestMessage>() }
}
it("Generates enum references") {
openApiTestAllSerializers(
"T0002__enummessage_post.json",
testMessageBasics(EnumMessage.getDefaultInstance())
) { testRoute<EnumMessage>() }
}
it("Generates repeated type references") {
openApiTestAllSerializers(
"T0003__repeatedmessage_post.json",
testMessageBasics(RepeatedMessage.getDefaultInstance())
) { testRoute<RepeatedMessage>() }
}
it("Generates nested type references") {
openApiTestAllSerializers(
"T0004__nestedmessage_post.json",
testMessageBasics(NestedMessage.getDefaultInstance())
) { testRoute<NestedMessage>() }
}
it("Generates nested map type references") {
openApiTestAllSerializers(
"T0005__nestedmapmessage_post.json",
testMessageBasics(NestedMapMessage.getDefaultInstance())
) { testRoute<NestedMapMessage>() }
}
}
}) })
/** /**
@ -256,3 +298,25 @@ fun testMessageBasics(message: GeneratedMessageV3): Map<KType, JsonSchema> {
} }
return resultSchema return resultSchema
} }
private const val DEFAULT_RESPONSE_DESCRIPTION = "A Successful Endeavor"
private const val DEFAULT_REQUEST_DESCRIPTION = "You gotta send it"
private const val DEFAULT_PATH_SUMMARY = "Great Summary!"
private const val DEFAULT_PATH_DESCRIPTION = "testing more"
private inline fun <reified T> Route.testRoute() {
install(NotarizedRoute()) {
post = PostInfo.builder {
summary(DEFAULT_PATH_SUMMARY)
description(DEFAULT_PATH_DESCRIPTION)
request {
requestType<Unit>()
description(DEFAULT_REQUEST_DESCRIPTION)
}
response {
responseCode(HttpStatusCode.OK)
responseType<T>()
description(DEFAULT_RESPONSE_DESCRIPTION)
}
}
}
}

View File

@ -0,0 +1,127 @@
{
"openapi": "3.1.0",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "Test API",
"version": "1.33.7",
"description": "An amazing, fully-ish 😉 generated API spec",
"termsOfService": "https://example.com",
"contact": {
"name": "Homer Simpson",
"url": "https://gph.is/1NPUDiM",
"email": "chunkylover53@aol.com"
},
"license": {
"name": "MIT",
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
}
},
"servers": [
{
"url": "https://myawesomeapi.com",
"description": "Production instance of my API"
},
{
"url": "https://staging.myawesomeapi.com",
"description": "Where the fun stuff happens"
}
],
"paths": {
"/": {
"post": {
"tags": [],
"summary": "Great Summary!",
"description": "testing more",
"parameters": [],
"requestBody": {
"description": "You gotta send it",
"required": true
},
"responses": {
"200": {
"description": "A Successful Endeavor",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SimpleTestMessage"
}
}
}
}
},
"deprecated": false
},
"parameters": []
}
},
"webhooks": {},
"components": {
"schemas": {
"SimpleTestMessage": {
"type": "object",
"properties": {
"myTestDouble": {
"type": "number",
"format": "double"
},
"myTestFloat": {
"type": "number",
"format": "float"
},
"myTestInt32": {
"type": "number",
"format": "int32"
},
"myTestInt64": {
"type": "number",
"format": "int64"
},
"myTestUint32": {
"type": "number",
"format": "int32"
},
"myTestUint64": {
"type": "number",
"format": "int64"
},
"myTestSint32": {
"type": "number",
"format": "int32"
},
"myTestSint64": {
"type": "number",
"format": "int64"
},
"myTestFixed32": {
"type": "number",
"format": "int32"
},
"myTestFixed64": {
"type": "number",
"format": "int64"
},
"myTestSfixed32": {
"type": "number",
"format": "int32"
},
"myTestSfixed64": {
"type": "number",
"format": "int64"
},
"myTestBool": {
"type": "boolean"
},
"myTestBytes": {
"type": "string"
},
"myTestString": {
"type": "string"
}
}
}
},
"securitySchemes": {}
},
"security": [],
"tags": []
}

View File

@ -0,0 +1,86 @@
{
"openapi": "3.1.0",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "Test API",
"version": "1.33.7",
"description": "An amazing, fully-ish 😉 generated API spec",
"termsOfService": "https://example.com",
"contact": {
"name": "Homer Simpson",
"url": "https://gph.is/1NPUDiM",
"email": "chunkylover53@aol.com"
},
"license": {
"name": "MIT",
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
}
},
"servers": [
{
"url": "https://myawesomeapi.com",
"description": "Production instance of my API"
},
{
"url": "https://staging.myawesomeapi.com",
"description": "Where the fun stuff happens"
}
],
"paths": {
"/": {
"post": {
"tags": [],
"summary": "Great Summary!",
"description": "testing more",
"parameters": [],
"requestBody": {
"description": "You gotta send it",
"required": true
},
"responses": {
"200": {
"description": "A Successful Endeavor",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EnumMessage"
}
}
}
}
},
"deprecated": false
},
"parameters": []
}
},
"webhooks": {},
"components": {
"schemas": {
"EnumMessage": {
"type": "object",
"properties": {
"corpus": {
"$ref": "#/components/schemas/Corpus"
}
}
},
"Corpus": {
"type": "string",
"enum": [
"CORPUS_UNSPECIFIED",
"CORPUS_UNIVERSAL",
"CORPUS_WEB",
"CORPUS_IMAGES",
"CORPUS_LOCAL",
"CORPUS_NEWS",
"CORPUS_PRODUCTS",
"CORPUS_VIDEO"
]
}
},
"securitySchemes": {}
},
"security": [],
"tags": []
}

View File

@ -0,0 +1,138 @@
{
"openapi": "3.1.0",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "Test API",
"version": "1.33.7",
"description": "An amazing, fully-ish 😉 generated API spec",
"termsOfService": "https://example.com",
"contact": {
"name": "Homer Simpson",
"url": "https://gph.is/1NPUDiM",
"email": "chunkylover53@aol.com"
},
"license": {
"name": "MIT",
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
}
},
"servers": [
{
"url": "https://myawesomeapi.com",
"description": "Production instance of my API"
},
{
"url": "https://staging.myawesomeapi.com",
"description": "Where the fun stuff happens"
}
],
"paths": {
"/": {
"post": {
"tags": [],
"summary": "Great Summary!",
"description": "testing more",
"parameters": [],
"requestBody": {
"description": "You gotta send it",
"required": true
},
"responses": {
"200": {
"description": "A Successful Endeavor",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RepeatedMessage"
}
}
}
}
},
"deprecated": false
},
"parameters": []
}
},
"webhooks": {},
"components": {
"schemas": {
"RepeatedMessage": {
"type": "object",
"properties": {
"repeatedField": {
"items": {
"$ref": "#/components/schemas/SimpleTestMessage"
},
"type": "array"
}
}
},
"SimpleTestMessage": {
"type": "object",
"properties": {
"myTestDouble": {
"type": "number",
"format": "double"
},
"myTestFloat": {
"type": "number",
"format": "float"
},
"myTestInt32": {
"type": "number",
"format": "int32"
},
"myTestInt64": {
"type": "number",
"format": "int64"
},
"myTestUint32": {
"type": "number",
"format": "int32"
},
"myTestUint64": {
"type": "number",
"format": "int64"
},
"myTestSint32": {
"type": "number",
"format": "int32"
},
"myTestSint64": {
"type": "number",
"format": "int64"
},
"myTestFixed32": {
"type": "number",
"format": "int32"
},
"myTestFixed64": {
"type": "number",
"format": "int64"
},
"myTestSfixed32": {
"type": "number",
"format": "int32"
},
"myTestSfixed64": {
"type": "number",
"format": "int64"
},
"myTestBool": {
"type": "boolean"
},
"myTestBytes": {
"type": "string"
},
"myTestString": {
"type": "string"
}
}
}
},
"securitySchemes": {}
},
"security": [],
"tags": []
}

View File

@ -0,0 +1,135 @@
{
"openapi": "3.1.0",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "Test API",
"version": "1.33.7",
"description": "An amazing, fully-ish 😉 generated API spec",
"termsOfService": "https://example.com",
"contact": {
"name": "Homer Simpson",
"url": "https://gph.is/1NPUDiM",
"email": "chunkylover53@aol.com"
},
"license": {
"name": "MIT",
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
}
},
"servers": [
{
"url": "https://myawesomeapi.com",
"description": "Production instance of my API"
},
{
"url": "https://staging.myawesomeapi.com",
"description": "Where the fun stuff happens"
}
],
"paths": {
"/": {
"post": {
"tags": [],
"summary": "Great Summary!",
"description": "testing more",
"parameters": [],
"requestBody": {
"description": "You gotta send it",
"required": true
},
"responses": {
"200": {
"description": "A Successful Endeavor",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NestedMessage"
}
}
}
}
},
"deprecated": false
},
"parameters": []
}
},
"webhooks": {},
"components": {
"schemas": {
"NestedMessage": {
"type": "object",
"properties": {
"nestedField": {
"$ref": "#/components/schemas/SimpleTestMessage"
}
}
},
"SimpleTestMessage": {
"type": "object",
"properties": {
"myTestDouble": {
"type": "number",
"format": "double"
},
"myTestFloat": {
"type": "number",
"format": "float"
},
"myTestInt32": {
"type": "number",
"format": "int32"
},
"myTestInt64": {
"type": "number",
"format": "int64"
},
"myTestUint32": {
"type": "number",
"format": "int32"
},
"myTestUint64": {
"type": "number",
"format": "int64"
},
"myTestSint32": {
"type": "number",
"format": "int32"
},
"myTestSint64": {
"type": "number",
"format": "int64"
},
"myTestFixed32": {
"type": "number",
"format": "int32"
},
"myTestFixed64": {
"type": "number",
"format": "int64"
},
"myTestSfixed32": {
"type": "number",
"format": "int32"
},
"myTestSfixed64": {
"type": "number",
"format": "int64"
},
"myTestBool": {
"type": "boolean"
},
"myTestBytes": {
"type": "string"
},
"myTestString": {
"type": "string"
}
}
}
},
"securitySchemes": {}
},
"security": [],
"tags": []
}

View File

@ -0,0 +1,146 @@
{
"openapi": "3.1.0",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "Test API",
"version": "1.33.7",
"description": "An amazing, fully-ish 😉 generated API spec",
"termsOfService": "https://example.com",
"contact": {
"name": "Homer Simpson",
"url": "https://gph.is/1NPUDiM",
"email": "chunkylover53@aol.com"
},
"license": {
"name": "MIT",
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
}
},
"servers": [
{
"url": "https://myawesomeapi.com",
"description": "Production instance of my API"
},
{
"url": "https://staging.myawesomeapi.com",
"description": "Where the fun stuff happens"
}
],
"paths": {
"/": {
"post": {
"tags": [],
"summary": "Great Summary!",
"description": "testing more",
"parameters": [],
"requestBody": {
"description": "You gotta send it",
"required": true
},
"responses": {
"200": {
"description": "A Successful Endeavor",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NestedMapMessage"
}
}
}
}
},
"deprecated": false
},
"parameters": []
}
},
"webhooks": {},
"components": {
"schemas": {
"NestedMapMessage": {
"type": "object",
"properties": {
"mapField": {
"additionalProperties": {
"type": "object",
"properties": {
"myVariable0": {
"$ref": "#/components/schemas/SimpleTestMessage"
},
"myVariable1": {
"$ref": "#/components/schemas/SimpleTestMessage"
}
}
},
"type": "object"
}
}
},
"SimpleTestMessage": {
"type": "object",
"properties": {
"myTestDouble": {
"type": "number",
"format": "double"
},
"myTestFloat": {
"type": "number",
"format": "float"
},
"myTestInt32": {
"type": "number",
"format": "int32"
},
"myTestInt64": {
"type": "number",
"format": "int64"
},
"myTestUint32": {
"type": "number",
"format": "int32"
},
"myTestUint64": {
"type": "number",
"format": "int64"
},
"myTestSint32": {
"type": "number",
"format": "int32"
},
"myTestSint64": {
"type": "number",
"format": "int64"
},
"myTestFixed32": {
"type": "number",
"format": "int32"
},
"myTestFixed64": {
"type": "number",
"format": "int64"
},
"myTestSfixed32": {
"type": "number",
"format": "int32"
},
"myTestSfixed64": {
"type": "number",
"format": "int64"
},
"myTestBool": {
"type": "boolean"
},
"myTestBytes": {
"type": "string"
},
"myTestString": {
"type": "string"
}
}
}
},
"securitySchemes": {}
},
"security": [],
"tags": []
}