• Logic • Communication • Choices available to each component Client User Interface Logic Communication Client Communication Endpoint Whatever you need Server
i.e. DOM rendering UI states, event flows etc. • Properties • Safe and clean UI logics • Requires sbt as a main build system • Main component on the client side! • Choices • Dom Builder: scalajs-dom, scalatags • RX/FRP: Binding.scala, OutWatch, airframe-rx- html • React Wrapper: scalajs-react, slinky • Flux: Diode Client User Interface Server
information between servers via HTTP • Properties • Interface matters! • Explicitly defined interface helps us a lot • Strictly-typed interface with Scala.js • Isomorphic architecture • Choices • RPC approach • IDL approach • Endpoint approach • Vanila REST Client Communication Client Server
interfaces in external IDL, and compile them with the provided tools • Pros • High interoperability • Existing community and ecosystem • Cons • Weaker type safety • No types, or at least, conversions are required • Sometimes Scala support is not matured • Need to learn IDL • Examples • OpenAPI, GraphQL, gRPC, ScalaPB, mu-scala, etc syntax = "proto3"; package com.example.protos; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } message HelloRequest { string name = 1; } message HelloReply { string message = 1; } .proto val channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext(true).buil d val blockingStub = GreeterGrpc.blockingStub(channel) val request = HelloRequest(name = "World") val reply: HelloReply = blockingStub.sayHello(request) private class GreeterImpl extends GreeterGrpc.Greeter { override def sayHello(req: HelloRequest) = { Future.successful(HelloReply(message = "Hello " + req.name)) } } Server Client
REST endpoints as values in Scala and retrieve client/server automatically. • Pros • No need to learn other language • Strictly typed in Scala • Definition Programmable • Interoperable with other languages • You can exploit standard HTTP REST • Cons • REST design must be considered • Some boilerplates is required (boring, but not complex) • Understanding of the library design is necessary • Examples • tapir, endpoints4s • My recommendation case class Person(id: Int, name: String) trait GreeterEndpoints extends algebra.Endpoints with algebra.JsonEntitiesFromSchemas with generic.JsonSchemas { val sayHello: Endpoint[Person, Counter] = endpoint(get(path / "hello"), ok(jsonResponse[String])) implicit lazy val personSchema: JsonSchema[Person] = genericJsonSchema } Endpoint object GreeterClient extends GreeterEndpoints with endpoints4s.xhr.thenable.Endpoints with endpoints4s.xhr.JsonEntitiesFromSchemas val helloResult: js.Thenable[String] = GreeterClient.sayHello(Person(1, "foo")) class GreetRoutes[F[_]: Sync] extends endpoints4s.http4s.server.Endpoints[F] with endpoints4s.http4s.server.JsonEntitiesFromSchemas with GreetEndpoints { val routes: HttpRoutes[F] = HttpRoutes.of( sayHello.implementedBy(person => s"Hello ${person.name} (id=${person.id})!") ) } Server Client
as Logic • Pros • Less intrusive • Self-contained in many cases • Best starting point for Scala.js • Cons • Applicability is limited • Logic component tends to be a small part of whole client codes. • Most of client codes are still in JS/AltJS • Understanding of Scala.js’s JS interoperability is necessary Client Server
+ a bit of JS optionally • Pros • Complete Scala experience! • ADT, pattern match, FP, etc. • Simple build system • Complete within sbt • sbt-scalajs, sbt-crosscompile, sbt-scalajs-bundler etc. • Cons • Hard to adopt the existing frontend ecosystem • There is no DefinitelyTypes for Scala.js! • Writing facades is always required (complex and boring) • (IMO) Psychological barrier to adopt JS • Requires determination! Client Server
as Communication Client • Pros • Explicit and strictly-typed client-server interface • Easily exploitable the existing frontend ecosystem • High Interoperability (not the case for RPC) • Cons • Most of client codes are still in JS/AltJS • Build definition tends to be complex • Both Sbt and JS bundler must be combined • Wrappers of Scala.js is sometimes required • boring, but not complex • Wrappers may be auto-generated • My recommendation Client Server
to incorporate Scala.js in your product • User Interface • Logic • Communication • Example architecture • Scala.js in Logic • All Scala • Scala.js in Communication • Enjoy Scala.js! Client User Interface Logic Communication Client Communication Endpoint Whatever you need Server