Hello,
Redoc supports the x-tagGroup
extension, which gives an additional layer of nesting in the endpoints column on the left hand-side of the generated website. See the pet store example:
I’m aware that I can extend the generated documentation with some primitive types, e.g keys with lists of strings etc. but how would I go about creating the tag group object?
I would have thought a case class with a Circe encoder/decoder would suffice but unfortunately not.
Any help would be greatly appreciated 
@gerryfletch I have just tried to add this extension in a pet project, and it works as expected.
- Define a case class for tag groups
case class TagGroupDocExtension(name: String, tags: List[String])
- Build a list of groups:
val tagGroupsExtension =
DocsExtension.of(
"x-tagGroups",
List(
TagGroupDocExtension(
"General",
List("pet", "store")
),
TagGroupDocExtension("User Management", List("user"))
)
)
- Annotate your endpoints with tags
val exampleEndpoint: sttp.tapir.Endpoint[Unit, Example, String, String, Any] = endpoint.get
.in("test" / path[Example]("testId"))
.out(stringBody)
.errorOut(stringBody)
.tag("store")
Make sure all tags listed in tagGroupsExtension
are used in your endpoints.
- Define documentation endpoints, referring to
tagGroupsExtension
val docEndpoints: List[ServerEndpoint[Any, IO]] = RedocInterpreter()
.fromServerEndpoints[IO](apiEndpoints, Info("title", "version"), List(tagGroupsExtension))
Note: If you additionally use OpenAPIDocsInterpreter
to create a yaml file, please note that the extensions will be specified in the end of the specs file.
- Bind your endpoints and start the server, the groups should be visible in the redoc UI.
@kciesielski do you mind sharing your imports for that snippet?
That’s precisely what I tried before, but couldn’t get the JsonCodec stuff to work:
Cannot find a codec between types: String and List[TagGroupDocExtension], formatted as: sttp.tapir.CodecFormat.Json
Sure, here are the imports I used to get circe generic autoderivation, Tapir schema generic autoderivation, and Tapir<>circe interop
import io.circe.generic.auto.*
import sttp.tapir.generic.auto.*
import sttp.tapir.json.circe.*
I must have been missing an import there - working a charm now, thanks ever so much @kciesielski !
1 Like