Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introducing Armeria (or Three Principles of a Good Framework)

Introducing Armeria (or Three Principles of a Good Framework)

This talk introduces the three core principles behind how Trustin Lee and his team designed and implemented Armeria and how they run their community to build the best web and RPC framework. You'll find this talk useful if you are curious to know what Armeria is or what you should focus on to build a good framework

Related talks:
- Writing a Java Library with Better Experience

Previously presented at:
- LINE+ developer meetup on April 14, 2022

Trustin Lee

April 14, 2022
Tweet

More Decks by Trustin Lee

Other Decks in Programming

Transcript

  1. @armeria_project line/armeria Start small Server server = Server.builder() .http(8080) .service("/hello/:name",

    (ctx, req) -> HttpResponse.of("Hello, %s!", ctx.pathParam("name"))) .build();
  2. @armeria_project line/armeria … grow … Server server = Server.builder() .http(8080)

    .service("/api/v1/...", …) .service("/internal/metrics", PrometheusExpositionService.of(…)) .service("/internal/health-check", HealthCheckService.of()) .decorator(LoggingService.newDecorator()) .decorator(MetricCollectingService.newDecorator(…)) .build();
  3. @armeria_project line/armeria … and grow! • Security – Authn/z, CORS,

    SAML • Rate-limiting • Distributed tracing • Debugging & management • <Your custom decorator>
  4. @armeria_project line/armeria Principle #1: Well-paced • Build services on top

    of simple core concepts – Easy to learn & easy to master • Let users start simple and grow bit by bit – Grown code should still look simple.
  5. @armeria_project line/armeria Server server = Server.builder() .http(8080) .service(GrpcService.builder() .addService(new GrpcHelloService())

    .build()) .build(); class GrpcHelloService extends HelloServiceGrpc.HelloServiceImplBase { ... } • Full example: https://github.com/line/armeria-examples/tree/master/grpc-service
  6. @armeria_project line/armeria Thrift Server server = Server.builder() .http(8080) .service("/hello", THttpService.of(new

    ThriftHelloService())) .build(); class ThriftHelloService implements HelloService.AsyncIface { ... } • Full example: https://github.com/line/armeria-examples/tree/master/thrift
  7. @armeria_project line/armeria Mix & Match! Server server = Server.builder() .http(8080)

    .service("/hello/rest", (ctx, req) -> HttpResponse.of("Hello, world!")) .service("/hello/thrift", THttpService.of(new ThriftHelloService())) .service(GrpcService.builder() .addService(new GrpcHelloService()) .build()) .build();
  8. @armeria_project line/armeria Armeria integrates with … • Languages • Frameworks

    • Protocols • Discovery • Tracing • Legacy Dropwizard Thrift DNS Eureka
  9. @armeria_project line/armeria Principle #2: Unopinionated (integration) • No side effect

    between integrations • No complex mandatory dependencies • All built on top of simple core constructs – Know how to add decorators or services? It’s likely you already know how to integrate with <X>.
  10. @armeria_project line/armeria 2-phase migration (Thrift gRPC) → 1) Run THttpService

    and GrpcService in a single Armeria server. 2) Remove THttpService from the Armeria server. 3) Profit! • Much less operational complexity – No reverse proxy such as Envoy & NGINX – No 2 ports or 2 server instances
  11. @armeria_project line/armeria It’s more than migration • Multi-protocol is the

    new normal. – gRPC + REST + GraphQL – Load balancer health checks – WebSocket (coming soon) – Static resources • One service, one port, one JVM – Operational complexity – Code and build complexity
  12. @armeria_project line/armeria Different core, different capability • Netty-based reactive HTTP

    runtime built from the ground up enables unsurpassably powerful integration. • All kinds of endpoints in the same port with minimal overhead – gRPC, Thrift, GraphQL, REST, … • Even Tomcat, Jetty and WebFlux • Decorators work for all endpoints – Metrics, Tracing, Rate-limiting, … • Even if it’s not implemented in the upstream
  13. @armeria_project line/armeria Different core, different capability • Structured logging –

    Programmatic access to everything about the request – Ingested by machines for analytics – ELK, Kafka, … • Abstraction layer with both HTTP/1 and 2 in mind – Your gRPC service suddenly starts to talk HTTP/1. – Your old Tomcat, Jetty and Thrift service suddenly start to talk HTTP/2. • HAPROXY, SOCKS, Protocol auto-detection, …
  14. @armeria_project line/armeria Principle #3: Community-friendly • It’s all about building

    a virtuous cycle a.Well-designed API that adheres to its principles b.Great developer experience c.More users and contributors w/ ideas d.Close collaboration with them e.(Repeat)
  15. @armeria_project line/armeria Ingredients that fuel virtuous cycle • Friendly yet

    honest atmosphere • Less hassles to contribute • Consistency – being true to the project goal • Applies to every aspect of the cycle: – Questions – Feedback – Code reviews
  16. @armeria_project line/armeria Recap • Well-paced – Easy to learn &

    easy to master • Unopinionated integration – Powered by custom reactive HTTP runtime • Community-friendly – Building a virtuous cycle to make an impact
  17. @armeria_project line/armeria Currently on our radar • Web-based dashboard •

    Richer route expressions • HTTP/3 • WebSocket / Socket.io • Dynamic reconfiguration • LiveReload / HotSwap • xDS protocol support • OpenAPI interoperability • UNIX domain sockets • Kotlin / Scala DSL • GraalVM native images • Command-line interface