diff --git a/core/src/main/scala/pl/iterators/baklava/core/model/RouteParameterRepresentation.scala b/core/src/main/scala/pl/iterators/baklava/core/model/RouteParameterRepresentation.scala index f4be7cb..230616d 100644 --- a/core/src/main/scala/pl/iterators/baklava/core/model/RouteParameterRepresentation.scala +++ b/core/src/main/scala/pl/iterators/baklava/core/model/RouteParameterRepresentation.scala @@ -1,18 +1,42 @@ package pl.iterators.baklava.core.model import scala.reflect.runtime.universe.TypeTag +import scala.util.Random case class RouteParameterRepresentation[T]( name: String, - required: Boolean, - sampleValue: T, - marshaller: T => String, + valueGenerator: () => T, + marshaller: T => String = RouteParameterRepresentation.marshaller[T] _, + required: Boolean = false, + seq: Boolean = false, + seqMin: Int = 2, + seqMax: Int = 5, enumValues: Option[Seq[T]] = None )(implicit typeTag: TypeTag[T]) { - lazy val marshall: String = marshaller(sampleValue) + lazy val sampleValue: T = + if (!seq) valueGenerator() else sys.error("sampleValue should not be called on seq parameter") + + lazy val seqSampleValue: Seq[T] = + if (seq) (0 until Random.nextInt(1 + seqMax - seqMin) + seqMin).map(_ => valueGenerator()) + else sys.error("seqSampleValue should not be called on seq parameter") lazy val enums: Option[Seq[String]] = enumValues.map(values => values.map(marshaller)) - lazy val scalaType: String = typeTag.tpe.toString + lazy val simpleType: String = typeTag.tpe.toString + + lazy val queryString: String = + if (seq) { + seqSampleValue.map(v => s"$name=${marshaller(v)}").mkString("&") + } else + s"$name=${marshaller(sampleValue)}" + +} + +object RouteParameterRepresentation { + def marshaller[T](value: T): String = + value match { + case string: String => string + case other => other.toString + } } diff --git a/core/src/main/scala/pl/iterators/baklava/core/model/RouteRepresentation.scala b/core/src/main/scala/pl/iterators/baklava/core/model/RouteRepresentation.scala index 3072b76..1666c69 100644 --- a/core/src/main/scala/pl/iterators/baklava/core/model/RouteRepresentation.scala +++ b/core/src/main/scala/pl/iterators/baklava/core/model/RouteRepresentation.scala @@ -34,9 +34,7 @@ case class RouteRepresentation[Request, Response]( val parametersPath = Option .when(requiredParams.nonEmpty) { requiredParams - .map { param => - s"${param.name}=${param.marshall}" - } + .map(_.queryString) .mkString("?", "&", "") } .getOrElse("") @@ -48,9 +46,7 @@ case class RouteRepresentation[Request, Response]( val parametersPath = Option .when(parameters.nonEmpty) { parameters - .map { param => - s"${param.name}=${param.marshall}" - } + .map(_.queryString) .mkString("?", "&", "") } .getOrElse("") @@ -64,4 +60,7 @@ case class RouteRepresentation[Request, Response]( def getParamValue[T](name: String): Option[T] = parameters.find(_.name == name).map(_.sampleValue.asInstanceOf[T]) + def getSeqParamValue[T](name: String): Option[Seq[T]] = + parameters.find(_.name == name).map(_.seqSampleValue.asInstanceOf[Seq[T]]) + } diff --git a/formatter-openapi/src/main/scala/pl/iterators/baklava/formatter/openapi/OpenApiFormatterWorker.scala b/formatter-openapi/src/main/scala/pl/iterators/baklava/formatter/openapi/OpenApiFormatterWorker.scala index a98e0dd..ad6e477 100644 --- a/formatter-openapi/src/main/scala/pl/iterators/baklava/formatter/openapi/OpenApiFormatterWorker.scala +++ b/formatter-openapi/src/main/scala/pl/iterators/baklava/formatter/openapi/OpenApiFormatterWorker.scala @@ -87,14 +87,21 @@ class OpenApiFormatterWorker(jsonSchemaToSwaggerSchemaWorker: JsonSchemaToSwagge private def queryParamsToParams(parameters: List[RouteParameterRepresentation[_]]): List[Parameter] = parameters.map { param => - val schema = new StringSchema - schema.setExample(param.sampleValue) + val itemSchema = new StringSchema + itemSchema.setExample(param.valueGenerator()) param.enums.foreach { values => - schema.setEnum(values.toList.asJava) + itemSchema.setEnum(values.toList.asJava) } + val schema: Schema[_] = + if (param.seq) { + val arraySchema = new ArraySchema + arraySchema.setItems(itemSchema) + arraySchema + } else itemSchema + val p = new Parameter() - p.setName(param.name) + if (param.seq) p.setName(s"${param.name}[]") else p.setName(param.name) p.setIn("query") p.setRequired(param.required) p.setSchema(schema) diff --git a/formatter/src/main/scala/pl/iterators/baklava/formatter/SimpleDocsFormatter.scala b/formatter/src/main/scala/pl/iterators/baklava/formatter/SimpleDocsFormatter.scala index 3695ebe..3a5f8d9 100644 --- a/formatter/src/main/scala/pl/iterators/baklava/formatter/SimpleDocsFormatter.scala +++ b/formatter/src/main/scala/pl/iterators/baklava/formatter/SimpleDocsFormatter.scala @@ -4,7 +4,6 @@ import com.github.andyglow.json.JsonFormatter import com.github.andyglow.jsonschema.AsValue import json.schema.Version.Draft07 import pl.iterators.baklava.core.model.EnrichedRouteRepresentation -import pl.iterators.baklava.core.utils.option.RichOptionCompanion import java.io.{File, FileWriter, PrintWriter} import scala.util.Try @@ -133,7 +132,13 @@ class SimpleDocsFormatter extends Formatter { }, Option.when(r.parameters.nonEmpty) { s"PARAMETERS" + - s"${r.parameters.map(h => s"${h.name} [${h.scalaType}] ${Option.when(h.required)(s"*").getOrElse("")}").mkString("
")}" + + s"${r.parameters + .map(h => + s"${h.name}${if (h.seq) "[]" else ""}${Option.when(h.required)(s"*").getOrElse("")}: ${h.simpleType}${if (h.seq) "[]" + else ""} " + + s"(${h.enums.map(enums => enums.mkString("possible values: ", ", ", "")).getOrElse(s"example: ${h.valueGenerator()}")})" + ) + .mkString("
")}" + s"" + s"ROUTE WITH MINIMAL PARAMS${r.routePathWithRequiredParameters}" + s"ROUTE WITH ALL PARAMS${r.routePathWithAllParameters}"