{"id":15999473,"url":"https://github.com/aesteve/fertx","last_synced_at":"2025-06-14T23:37:47.509Z","repository":{"id":87789466,"uuid":"123937082","full_name":"aesteve/fertx","owner":"aesteve","description":"Functional Vert.x Web + Scala (inspired by Akka http)","archived":false,"fork":false,"pushed_at":"2020-04-19T00:03:31.000Z","size":337,"stargazers_count":4,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-13T17:51:28.626Z","etag":null,"topics":["scala","vertx","vertx-web"],"latest_commit_sha":null,"homepage":null,"language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aesteve.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-05T15:10:59.000Z","updated_at":"2021-04-26T18:13:26.000Z","dependencies_parsed_at":null,"dependency_job_id":"ecc55256-13ea-47be-b74e-91eb0227d5cd","html_url":"https://github.com/aesteve/fertx","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aesteve%2Ffertx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aesteve%2Ffertx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aesteve%2Ffertx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aesteve%2Ffertx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aesteve","download_url":"https://codeload.github.com/aesteve/fertx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247675609,"owners_count":20977378,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["scala","vertx","vertx-web"],"created_at":"2024-10-08T08:43:24.823Z","updated_at":"2025-04-07T15:14:11.480Z","avatar_url":"https://github.com/aesteve.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Fertx: Functional Vert.x Web DSL\n\nFertx is a functional way of dealing with Vert.x web's Route declaration.\n\n### Minimalistic example:\n\n```scala\nHEAD(\"api\" / \"health\").map { () =\u003e\n  OK\n}\n```\n`map` can be replaced by `apply` if you find it more natural. The example above could be written:\n```scala\nHEAD(\"api\" / \"health\") { () =\u003e\n  OK\n}\n```\n\n\n### Extract data from path:\n\n```scala \nGET(\"api\" / \"todos\" / 'id.as[Int]) { todoId =\u003e\n  if (todoId \u003e 10) { // todoId is an Int\n    NotFound\n  } else {\n    OK\n  }\n}\n```\n\n### Extract data from path and query:\n```scala\nGET(\"api\" / \"todos\" / 'id.as[Int])\n  .query(\"filterById\")\n  .map { (todoId, filterValue) =\u003e\n    // ...\n  }\n}\n```\n\n### Return response body:\nLet's try:\n```scala\ncase class Todo(id: Int)\nGET(\"api\" / \"todos\" / 'id.as[Int])\n  .produces(`text/plain`)\n  .map { todoId =\u003e \n    OK(Todo(todoId))   \n  }\n```\nThe compiler will complain he cannot find neither a ``ResponseMarshaller[`text/plain`, Todo]`` nor an ``ErrorMarshaller[`text/plain`]``\nThis is the way to ensure, at compile time, that you're not using \"unmarshallable\" objects.\nAnd indeed, what should a `Todo` instance look like once sent to `text/plain` ?\n\n```scala\ncase class Todo(id: Int)\n// you'll define a proper way to marshall a Todo instance to plain text\nimplicit val todoTextWriter = new ResponseMarshaller[`text/plain`, Todo] {\n  override def handle(todo: Todo, resp: HttpServerResponse): Unit =\n    resp.end(todo.id.toString)\n} \n// you also have to provide a way to handle errors in plain/text, you can use fertx built-in marshaller\nimport com.github.aesteve.dsl.marshallers.SimpleErrorTextMarshaller \nGET(\"api\" / \"todos\" / 'id.as[Int])\n  .produces(`text/plain`)\n  .map { todoId =\u003e \n    OK(Todo(todoId))   \n  }\n```\nNow compiles.\nYou can deal with your domain objects in a safe way.\nYou can also choose the strategy you wan for marshalling within your application. Either \"one per domain class\", or a \"generic one for every object\".\nAlso, you can scope the `implicit` wherever you want. Either a global import for all your routes, or like in the example, very close to the route definition.\n\n### Read request body:\n\nThe same way, we have to define a ``RequestUnmarshaller[`text/plain`, Todo]``.\n```scala\ncase class Todo(id: Int)\nimplicit val todoStrUnmarshaller = new RequestUnmarshaller[`text/plain`, Todo] {\n  override def extract(rc: RoutingContext): Either[MalformedBody, Todo] =\n    try {\n      Right(rc.getBodyAsString.get.toInt)\n    } catch {\n      case _: Exception =\u003e Left(new MalformedBody)\n    }\n}\nPOST(\"api\" / \"todos\")\n  .accepts(`text/plain`)\n  .body[Todo] // no problem, since the Unmarshaller is in the scope\n  .map { todo =\u003e \n    // save it or whatever\n    Accepted // doesn't even need to mention \"produces\" since we're not producing any content\n  }\n\n```\n\n### Deal with asynchronous responses\n\n```scala\ndef longComputation(): Future[Long] = ???\nPOST(\"api\" / \"compute\")\n .produces(`text/plain`) // given we have a ResponseMarshaller[`text/plain`, Long] in scope\n .flatMap { () =\u003e\n  longComputation().map(OK(_)) \n }\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faesteve%2Ffertx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faesteve%2Ffertx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faesteve%2Ffertx/lists"}