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

かにさんタワーバトル

 かにさんタワーバトル

   🦀
  🦀
🦀🦀🦀 🦀
🦀🦀🦀🦀🦀🦀🦀
🦀🦀🦀🦀🦀🦀🦀🦀

sadnessOjisan

October 21, 2023
Tweet

More Decks by sadnessOjisan

Other Decks in Programming

Transcript

  1. About me { “name”: “Yuta Ide”, “account”: “@sadnessOjisan”, “belong”: “Nikkei

    / Japanese News Paper Company”, “lang”: [“JS/TS(2018-)”, “Rust(2022-)”], “misc”: “rust.tokyo 2019 stuff” }
  2. We adopt micro frontend architecture CDN (Fastly) Node.js Article Detail

    Search Market Article Index connect by anchor tags We love HTTP and HTML … handlebars handlebars VCL + handlebars react split with vertical aggregate
  3. We adopt micro frontend architecture CDN (Fastly) Node.js Article Detail

    Topic Index Search Market Article Index connect by anchor tags We love HTTP and HTML handlebars handlebars handlebars VCL + handlebars We maintain 24 micro frontend services with limited resource
  4. We adopt micro frontend architecture CDN (Fastly) Node.js Article Detail

    Topic Index Search Market Article Index connect by anchor tags We love HTTP and HTML handlebars handlebars handlebars VCL + handlebars We maintain 24 micro frontend services with Node.js v12 (current is v21) (Including tooling, we maintain 40↑ projects with old Node.js)
  5. We adopt micro frontend architecture CDN (Fastly) Node.js Article Detail

    Topic Index Search Market Article Index connect by anchor tags We love HTTP and HTML handlebars handlebars handlebars VCL + handlebars We are now replacing v12 → v16 → v18→ v20 for 11 months 😇
  6. Updating Node.js and library is so hard • Node.js releases

    a major update every 6 months. It is frequent. • We must update Node.js version for EOL. • After updating Node.js, sometimes (I often experience) fail npm install, or fail building app with bundler. Due to node-gyp, node-sass, --openssl-legacy-provider… 😭 We need maintanability
  7. Should we follow the new lang and lib version? application

    With UI JSON API Developing Stable Sometimes it needs maintenance e.g. serious security patch, EOL We always doesn’t have to keep up with each new version. Always it needs maintenance
  8. Should we follow the new lang and lib version? application

    With UI JSON API Developing Stable Sometimes it needs maintenance e.g. serious security patch, EOL We always doesn’t have to keep up with each new version. Always it needs maintenance We considered replacing a new tech stack
  9. Our requirements for the new tech stack are… • Typing

    • Lint • Test • OAS (Open API Schema) • Documentation / Gen Doc • Clever pkg manager • Error handling • Logging / Tracing Rich and modern feature help our maintenance
  10. We want to replace it… The choice is… • Node.js

    v20 + TypeScript + eslint + vitest • Golang • Rust How about Rust?
  11. Rust includes… • Typing → strict typing. e.g. lifetime, no

    hatch except for unsafe • Lint → Clippy • Test → cargo test, in-source testing • OAS → 3rd party lib. e.g. utopia • Documentation / Gen Doc → cargo doc, utopia • Clever pkg manager → cargo • Error handling → Result. thiserror (de facto 3rd party lib) • Logging / Tracing → tracing (de facto 3rd party lib)
  12. Rust with Nikkei Some teams at Nikkei adopted Rust in

    production • Using Fastly Computing@Edge for delivery and handling access log. ◦ access log server handles 6500 req/sec • Wave BFF Server uses Rust for schemaful endpoint with gRPC and HTTP. ◦ Wave: https://hack.nikkei.com/blog/advent20201218/ So I’m in a good environment to choose Rust. But…
  13. Is choosing Rust appropriate? My concern is • Rust is

    not batteries-included lang. We must choose 3rd party libs. ◦ async runtime ◦ web server ◦ common util (serializer, date, …) • Long-term stability of 3rd party ecosystems.
  14. But we chose Rust • Rust itself is solid •

    Although Rust is not batteries-included lang, there are many de facto libs. (e.g. tokio, thiserror, anyhow, chrono…) • Rust can find breaking changes easily at compile time.
  15. We choose axum as Web FW • hyper ◦ primitive.

    I need router. • actix-web ◦ good choice • axum ◦ tokio-rs maintain this. I believe maintenance continue to If we choose a web fw, the choices are
  16. Axum architecture • Axum is HTTP Server FW. • Axum

    = hyper + tower. hyper future future future future tower service call user req response tokio
  17. HTTP Server with Hyper • Hyper is a tokio based

    HTTP library. • It’s too primitive. (e.g. Hyper doesn’t have a router.) Hyper is not for web app developer but for library developer https://hyper.rs/
  18. Tower provides abstract of req → res • Official description

    is `async fn(Request) -> Result<Response, Error>` • Tower provides a trait for creating middleware. • HTTP Server can be described as composition of middlewares. Router, Auth, Logger, Retry, Rate Limit, Timeout, and so on. https://github.com/tower-rs/tower
  19. Service is a main concept of tower • Service is

    an abstract model of processing req -> res. • Main part is call function. This accepts a request and returns a response future. https://docs.rs/tower/latest/tower/trait.Service.html
  20. Layer can stack Services • Each tower service should have

    a single role. (SRP of SOLID) • User can combine services. In mental model, that’s stacking service on layer. requests | v +----- layer_three -----+ | +---- layer_two ----+ | | | +-- layer_one --+ | | | | | | | | | | | handler | | | | | | | | | | | +-- layer_one --+ | | | +---- layer_two ----+ | +----- layer_three -----+ | v responses https://docs.rs/axum/latest/axum/middleware/index.html
  21. • Router is a Tower Service in axum. call return

    Oneshot which is tower service and have handler Fn. • Register path and handler • Handler value is into HTTP Response, the converter is also tower service
  22. Router is a Tower Service in axum • Router’s role

    is matching path, and execute handler. • Router is implemented as tower Service. call finds matched path, and execute handler function. handler is also service. • Router’s call return RouteFuture. This includes Oneshot struct which impl Future poll of calling handler service. https://docs.rs/axum/latest/axum/struct.Router.html
  23. Register path and handler • Router is a KV store.

    • key is path • value is handler https://docs.rs/axum/latest/axum/struct.Router.html#method.route
  24. Handler value is into HTTP Response, the converter is also

    tower service • Routing handler is a function. The return value can be HTTP Response with any Status Code. • IntoResponse trait control it. str and Result and many struct has default IntoResponse impl. So, automatically convert to HTTP. • Endpoint have MapResponse struct which has into_response Fn. MapResponse is also tower service. The service is called in polling Oneshot. HTTP/1.1 200 OK content-type: text/plain; charset=utf-8 content-length: 13 date: Thu, 19 Oct 2023 03:22:40 GMT Hello, World
  25. I want to avoid tight coupling with axum • Although

    axum is popular Web FW, it is 3rd party. • Sometimes our app may fail updating axum version because of our wrong implement.
  26. How to avoid tight coupling with axum • Introduce Layered

    architecture, don’t use axum except for controller • Use tower service • Create E2E test
  27. Introduce Layered Architecture • Cargo can manage dependency graph through

    its workspaces feature.(e.g. controller cannot import repository) • I recommend you split your application into modules as it grows • And use axum only in controller and router. entity repository service usecase controller [package] name = "controller" [dependencies] axum = "0.6.20" entity = { path = "../entity" } usecase = { path = "../usecase" }
  28. Separation of cross-cutting concerns • Separation of cross-cutting concerns with

    tower. • Middleware is auth, logging, rate limit, delay, retry and so on. • Any layer from any framework is reusable if it implements tower interface. axtix-web is not tower based FW. But that middleware is like tower service. https://actix.rs/docs/middleware
  29. Case: Easily move to hyper • Axum = hyper +

    tower • We can use hyper directly • service_fn transform function to Service • Axum router’s handler is just function which return &str, Result and so on. It’s reusable. • For hyper v1, it may need tower-hyper-http-body-compat. Service is general. can run axum router handler
  30. Conclusion • Although developing HTTP server in Rust require 3rd

    party FW, Rust would be good choice. • Most FW use simple function as router, so you can easily replace to each library. • For replace, let’s adopt layered architecture, and use FW in only router and controller. • About AOP logic, If we adopt tower interface, we may be able to replace to each library because other library also adopt tower or tower like Service. So I use tower based FW.