Sitemap

omhs 0.1.0 — back after ~5 years.

1 min readAug 14, 2026

--

A long time ago I wrote a tiny Netty wrapper because I didn’t want to pull heavy dependencies into a project — just Sinatra-like routing. And now, five years later, it’s on Scala 3.

I tried before and dropped it (life got busy). This time it’s done.

Get Mike’s stories in your inbox

Join Medium for free to get updates from this writer.

What’s in this release:

  • Scala 3 alongside 2.13 — same DSL
  • Netty 4.1.137, refreshed play-json / circe / jsoniter modules
  • Maven Central (omhs-dsl + JSON support)
  • CI on both Scala versions

The hard part was the routing macros. On Scala 2, ~> expanded into an anonymous ExecutableRule subclass. Scala 3 quoted macros don’t generate that cleanly, so ExecutableRule now takes a runner: List[ParamDef[_]] => AsyncResult, and the macro only builds that function. Same DSL, different codegen.

Artefacts are here.

How to use:

// scala
import com.github.fntz.omhs._
import com.github.fntz.omhs.playjson.JsonSupport
import RoutingDSL._
import play.api.libs.json.{Format, Json}
import scala.concurrent.Future

case class Person(id: Int, name: String)

@main def main(): Unit = {
implicit val personJson: Format[Person] = Json.format[Person]
implicit val personBodyReader: BodyReader[Person] = JsonSupport.reader[Person]()
implicit val personBodyWriter: BodyWriter[Person] = JsonSupport.writer[Person]()

import AsyncResult.Implicits._
import scala.concurrent.ExecutionContext.Implicits.global

val simpleGetRoute = get("ping") ~> { () =>
"pong"
}

val getWithParamsRoute = get("bar" / string) ~> { (x: String) =>
s"given: $x"
}

val postPersonRoute = post("person" <<< body[Person]) ~> { (p: Person) =>
val x = p.copy(name = "new")
Future(x)
}

val route1 = new Route().addRules(
simpleGetRoute,
getWithParamsRoute,
postPersonRoute
)

val server = OMHSServer.init(9000, route1.toHandler(Setup.default), None)

server.start()

sys.addShutdownHook(server.stop())
new java.util.concurrent.CountDownLatch(1).await()
}

--

--

Mike
Mike

Written by Mike

I build distributed systems and real-time data pipelines. 10+ years in backend engineering. Focused on Kafka, microservices, and high-load systems. #golang