{"id":28393022,"url":"https://github.com/http4s/http4s-armeria","last_synced_at":"2025-10-13T19:13:56.932Z","repository":{"id":38039808,"uuid":"284596548","full_name":"http4s/http4s-armeria","owner":"http4s","description":"Armeria backend for http4s","archived":false,"fork":false,"pushed_at":"2025-06-14T06:54:55.000Z","size":669,"stargazers_count":60,"open_issues_count":3,"forks_count":10,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-06-14T07:45:17.387Z","etag":null,"topics":["armeria","http4s"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/http4s.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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,"zenodo":null}},"created_at":"2020-08-03T03:43:27.000Z","updated_at":"2025-06-14T06:54:45.000Z","dependencies_parsed_at":"2023-10-24T08:29:44.408Z","dependency_job_id":"5bef799b-2426-48e3-b653-e47e57f54160","html_url":"https://github.com/http4s/http4s-armeria","commit_stats":{"total_commits":194,"total_committers":8,"mean_commits":24.25,"dds":0.6030927835051547,"last_synced_commit":"8daddcaef84405f3d4e8d4417709934214dcdab7"},"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/http4s/http4s-armeria","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/http4s%2Fhttp4s-armeria","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/http4s%2Fhttp4s-armeria/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/http4s%2Fhttp4s-armeria/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/http4s%2Fhttp4s-armeria/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/http4s","download_url":"https://codeload.github.com/http4s/http4s-armeria/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/http4s%2Fhttp4s-armeria/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262022037,"owners_count":23246239,"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":["armeria","http4s"],"created_at":"2025-05-31T15:10:28.134Z","updated_at":"2025-10-13T19:13:51.910Z","avatar_url":"https://github.com/http4s.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# http4s-armeria\n\n[![Maven Central](https://img.shields.io/maven-central/v/org.http4s/http4s-armeria-server_2.13?versionPrefix=0.)](https://img.shields.io/maven-central/v/org.http4s/http4s-armeria-server_2.13?versionPrefix=0.)\n![Build Status](https://github.com/http4s/http4s-armeria/actions/workflows/ci.yml/badge.svg?branch=main)\n\n\n[Http4s] server and client on [Armeria]\n\n## Highlights\n\n- You can run Http4s services on top of Armeria's asynchronous and reactive server.\n- You can maximize your service and client with Armeria's [awesome features](https://armeria.dev/docs#features)\n  such as:\n    - gRPC server and client\n    - Circuit Breaker\n    - Automatic retry\n    - Dynamic service discovery\n    - Distributed tracing\n    - [and](https://armeria.dev/docs/server-docservice) [so](https://armeria.dev/docs/server-thrift) [on](https://armeria.dev/docs/advanced-metrics)\n\n## Current status\n\nTwo series are currently under active development: the `0.x` and `1.0-x` release milestone series.\nThe first depends on the `http4s-core`'s `0.23` series and belongs to the [main branch].\nThe latter is for the cutting-edge `http4s-core`'s `1.0-x` release milestone series and belongs to the [series/1.x branch].\n\n## Installation\n\nAdd the following dependencies to `build.sbt`\n```sbt\n// For server\nlibraryDependencies += \"org.http4s\" %% \"http4s-armeria-server\" % \"\u003clastest-version\u003e\"\n// For client\nlibraryDependencies += \"org.http4s\" %% \"http4s-armeria-client\" % \"\u003clastest-version\u003e\"\n```\n\n## Quick start\n\n### http4s integration\n\n#### Run your http4s service with [Armeria server](https://armeria.dev/docs/server-basics)\n\nYou can bind your http4s service using `ArmeriaServerBuilder[F].withHttpRoutes()`.\n\n```scala\nimport cats.effect._\nimport com.linecorp.armeria.common.metric.{MeterIdPrefixFunction, PrometheusMeterRegistries}\nimport com.linecorp.armeria.server.metric.{MetricCollectingService, PrometheusExpositionService}\nimport org.http4s.armeria.server.{ArmeriaServer, ArmeriaServerBuilder}\n\nobject ArmeriaExample extends IOApp {\n  override def run(args: List[String]): IO[ExitCode] =\n    ArmeriaExampleApp.resource[IO].use(_ =\u003e IO.never).as(ExitCode.Success)\n}\n\nobject ArmeriaExampleApp {\n  def builder[F[_]: ConcurrentEffect: ContextShift: Timer]: ArmeriaServerBuilder[F] = {\n    val registry = PrometheusMeterRegistries.newRegistry()\n    val prometheusRegistry = registry.getPrometheusRegistry\n    ArmeriaServerBuilder[F]\n      .bindHttp(8080)\n      // Sets your own meter registry\n      .withMeterRegistry(registry)\n      // Binds HttpRoutes to Armeria server\n      .withHttpRoutes(\"/http4s\", ExampleService[F].routes())\n      // Adds PrometheusExpositionService provided by Armeria for exposing Prometheus metrics\n      .withHttpService(\"/metrics\", PrometheusExpositionService.of(prometheusRegistry))\n      // Decorates your services with MetricCollectingService for collecting metrics\n      .withDecorator(\n        MetricCollectingService.newDecorator(MeterIdPrefixFunction.ofDefault(\"server\")))\n  }\n\n  def resource[F[_]: ConcurrentEffect: ContextShift: Timer]: Resource[F, ArmeriaServer[F]] =\n    builder[F].resource\n}\n```\n\n#### Call your service with http4s-armeria client\n\nYou can create http4s client using `ArmeriaClientBuilder`.\n\n```scala\nimport com.linecorp.armeria.client.circuitbreaker._\nimport com.linecopr.armeria.client.logging._\nimport com.linecopr.armeria.client.retry._\nimport org.http4s.armeria.client.ArmeriaClientBuilder \n\nval client: Client[IO] = \n  ArmeriaClientBuilder\n    .unsafe[IO](s\"http://127.0.0.1:${server.activeLocalPort()}\")\n    // Automically retry on unprocessed requests\n    .withDecorator(RetryingClient.newDecorator(RetryRule.onUnprocessed()))\n    // Open circuit on 5xx server error status\n    .withDecorator(CircuitBreakerClient.newDecorator(CircuitBreaker.ofDefaultName(),\n                                                     CircuitBreakerRule.onServerErrorStatus()))\n    // Log requests and responses\n    .withDecorator(LoggingClient.newDecorator())\n    .withResponseTimeout(10.seconds)\n    .build()\n    \nval response = client.expect[String](\"Armeria\").unsafeRunSync()\n```\n\n### fs2-grpc integration\n\n#### Run your [fs2-grpc](https://github.com/fiadliel/fs2-grpc) service with Armeria [gRPC server](https://armeria.dev/docs/server-grpc)\n\nAdd the following dependencies to `build.sbt`.\n\n```sbt\nlibraryDependencies += Seq(\n  \"com.linecorp.armeria\" % \"armeria-grpc\" % \"1.5.0\",\n  \"com.linecorp.armeria\" %% \"armeria-scalapb\" % \"1.5.0\")\n```\n\nAdd your fs2-grpc service to `GrpcService`.\n\n```scala\nimport com.linecorp.armeria.server.grpc.GrpcService\nimport com.linecorp.armeria.common.scalapb.ScalaPbJsonMarshaller\n\n// Build gRPC service\nval grpcService = GrpcService\n  .builder()\n  .addService(HelloServiceFs2Grpc.bindService(new HelloServiceImpl))\n  // Register `ScalaPbJsonMarshaller` to support gRPC JSON format\n  .jsonMarshallerFactory(_ =\u003e ScalaPbJsonMarshaller())\n  .enableUnframedRequests(true)\n  .build()\n```\n\nYou can run http4s service and gRPC service together with sharing a single HTTP port.\n\n```scala\nArmeriaServerBuilder[IO]\n  .bindHttp(httpPort)\n  .withHttpServiceUnder(\"/grpc\", grpcService)\n  .withHttpRoutes(\"/rest\", ExampleService[IO].routes())\n  .resource\n```\n\n#### Call your gRPC service using fs2-grpc with Armeria [gRPC client](https://armeria.dev/docs/client-grpc)\n\n```scala\nimport com.linecorp.armeria.client.Clients\nimport com.linecorp.armeria.client.grpc.{GrpcClientOptions, GrpcClientStubFactory}\n\nval client: HelloServiceFs2Grpc[IO, Metadata] =\n Clients\n   .builder(s\"gproto+http://127.0.0.1:$httpPort/grpc/\")\n   // Add a circuit breaker for your gRPC client\n   .decorator(CircuitBreakerClient.newDecorator(CircuitBreaker.ofDefaultName(),\n                                                CircuitBreakerRule.onServerErrorStatus()))\n   .option(GrpcClientOptions.GRPC_CLIENT_STUB_FACTORY.newValue(new GrpcClientStubFactory {\n     // Specify `ServiceDescriptor` of your generated gRPC stub\n     override def findServiceDescriptor(clientType: Class[_]): ServiceDescriptor =\n       HelloServiceGrpc.SERVICE\n\n     // Returns a newly created gRPC client stub from the given `Channel`\n     override def newClientStub(clientType: Class[_], channel: Channel): AnyRef =\n       HelloServiceFs2Grpc.stub[IO](channel)\n\n   }))\n   .build(classOf[HelloServiceFs2Grpc[IO, Metadata]])\n```\n\nVisit [examples](./examples) to find a fully working example.\n\n[http4s]: https://http4s.org/\n[armeria]: https://armeria.dev/\n[main branch]: https://github.com/http4s/http4s-armeria/tree/main\n[series/1.x branch]: https://github.com/http4s/http4s-armeria/tree/series/1.x\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhttp4s%2Fhttp4s-armeria","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhttp4s%2Fhttp4s-armeria","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhttp4s%2Fhttp4s-armeria/lists"}