# Custom config endpoint (either HOCON or JSON) - json type is string instead of object

**URL:** <https://softwaremill.community/t/custom-config-endpoint-either-hocon-or-json-json-type-is-string-instead-of-object/80>\
**Category:** tapir\
**Created:** [January 6, 2023, 7:43am UTC](https://softwaremill.community/t/custom-config-endpoint-either-hocon-or-json-json-type-is-string-instead-of-object/80 "2023-01-06T07:43:06Z")\
**Posts on this page:** 1\
**Showing post:** 1

<div class="post-metadata">

**Author:** ![hochgi](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/hochgi/32/32_2.png) [@hochgi](https://softwaremill.community/u/hochgi)\
**Post date:** [January 6, 2023, 7:43am UTC](https://softwaremill.community/t/custom-config-endpoint-either-hocon-or-json-json-type-is-string-instead-of-object/80/1 "2023-01-06T07:43:06Z")

</div>

We’ve implemented an endpoint exposing our typesafe config object (simplified from our real code):

```auto
// https://github.com/lightbend/config/blob/master/HOCON.md#mime-type
case class Hocon() extends CodecFormat {
  override val mediaType: MediaType = MediaType("application", "hocon")
}

val hoconBody: EndpointIO.Body[String, Config] = EndpointIO.Body(
  bodyType = stringBody.bodyType,
  codec = stringBody.codec.format(Hocon()).map(s => ConfigFactory.parseString(s))(_.root().render()),
  info = EndpointIO.Info.empty)

val parseJSON: String => DecodeResult[Config] = inputString => Try {
  ConfigFactory.parseString(
    inputString,
    ConfigParseOptions
      .defaults()
      .setSyntax(ConfigSyntax.JSON))
}.fold(DecodeResult.Error(inputString, _), DecodeResult.Value.apply)
val formatJSON: Config => String = _.root().render(
  ConfigRenderOptions
    .concise()
    .setJson(true))

```

and:

```auto
// this is probably wrong, but not sure how to fix
val configCustomJsonCodec: JsonCodec[Config] = Codec.json[Config](parseJSON)(formatJSON)(Schema.string[Config])

```

The endpoint itself is defined by (simplified from original):

```auto
val paths: EndpointInput.PathCapture[List[String]] = path[String]
  .name("path")
  .description("Configuration key paths, separated by ','")
  .map(_.split(',').toList)(_.mkString(","))

val configAtPath = customBase
  .name("configAtPath")
  .description("Get configuration for some path(s)")
  .in(paths)
  .get
  .out(oneOfBody(hoconBody, customCodecJsonBody[Config](configCustomJsonCodec)))

```

and logic is implemented with (also simplified):

```auto
val config: Config = …

configAtPath.serverLogicPure(traversePaths(config, _))

def traversePaths(config: Config, paths: List[String]): Either[ManagedError, Config] = {
  val (errors, confs) = paths.partitionWith(getConfig(config, _))
  if (errors.isEmpty) Right(confs.reduce(_ withFallback _))
  else Left(NotFound(errors.mkString("\n")))
}

def getConfig(config: Config, path: String): Either[ManagedError, Config] =
  if (config.hasPath(path)) Right(config.withOnlyPath(path))
  else Left(NotFound(s"'$path' does not exist in configuration."))

```

The thing is, that the resulting schema has responses section that looks like:

```yaml
responses:
  '200':
    description: ''
    content:
      application/hocon:
        schema:
          type: string
      application/json:
        schema:
          type: string

```

And it seems like I should have `type: object` instead of `type: string` for the JSON part, but since I used `Schema.string[Config]` for `configCustomJsonCodec` it’s probably why it’s a string.  
But I couldn’t figure out what to use for a free form JSON object like that.

Is there an easy fix I’m missing here?  
Thanks!

---

_[View the full topic](https://softwaremill.community/t/custom-config-endpoint-either-hocon-or-json-json-type-is-string-instead-of-object/80)._
