Slide 1

Slide 1 text

WebAssembly Unleashed: Powering Server-Side Applications. Made with đź’™

Slide 2

Slide 2 text

Chris Fuentes • Geek & Software Engineer. • I’m from El Salvador, living in Tokyo. • Open Source and community lover 💖 • Google Developer Group Leader 🇸🇻 About me :) @chrisft25

Slide 3

Slide 3 text

What if… the same code could be used anywhere? on the web, cloud, embedded devices or your toaster…

Slide 4

Slide 4 text

Portability • Portability is one of the biggest goal in software development, and we have specially seen this in the Javascript ecosystem since Node.js was born. • But, what if we can be polyglots and have the best performance?

Slide 5

Slide 5 text

✨ Introducing WebAssembly✨

Slide 6

Slide 6 text

WebAssembly • First appeared on March 2017. • A high-performance, portable, binary instruction format. • Designed for browsers. • Port server-side code to the browser. • Generates modules. Our old friend

Slide 7

Slide 7 text

Designed for browsers… can we use it somewhere else? Yes :)

Slide 8

Slide 8 text

WASM Runtimes And many more…

Slide 9

Slide 9 text

• Easy install as a library. • Sandboxed runtime. • Allow us to use the WASM modules inside of a host language (Go, Rust, Ruby, etc.)

Slide 10

Slide 10 text

Are we ready to use WASM in server-side languages? Yes and no… let me explain

Slide 11

Slide 11 text

Challenges • We can’t perform I/O operations in a server-side runtime. • Type-safety development

Slide 12

Slide 12 text

WebAssembly System Interface (WASI) • A group of standards-track API speci f ications for software compiled to the WebAssembly standard. WASI is designed to provide a secure standard interface for applications that can be compiled to Wasm from any language, and that may run anywhere—from browsers to clouds to embedded devices. • WASI P2 was released on February 2024.

Slide 13

Slide 13 text

Available APIs at this moment

Slide 14

Slide 14 text

FileSystem APIs • Read-via-stream. Return a stream for reading from a f ile. • Write-via-stream. Return a stream for writing to a f ile • Sync-data. Synchronize the data of a f ile to disk. • Read-directory. Read directory entries. • Many more… https://github.com/WebAssembly/wasi- f ilesystem

Slide 15

Slide 15 text

HTTP APIs • Outgoing-handler. Allows a module to make HTTP requests (similar to a fetch() operation) to external servers. • Incoming-handler. Allows the host environment to deliver HTTP requests to the module. This is useful for creating server-like WebAssembly applications capable of responding to HTTP requests.

Slide 16

Slide 16 text

Socket APIs • Instance-network. Allows querying and managing network interfaces and associated IP addresses. • IP-name-lookup. Provides APIs for resolving domain names to IP addresses. • TCP-create-socket. Enables the creation of TCP sockets. • TCP. Includes functions to manage TCP socket connections, send/receive data, and close connections. • UDP-create-socket. Facilitates the creation of UDP sockets. • UDP. Handles data transmission and reception for UDP sockets.

Slide 17

Slide 17 text

Now, we can build • Modules that read/write f iles. • Modules that perform HTTP requests • Very useful for HTTP-based microservices ;) • Modules that open socket connections with databases. • Modules that can instance queues in message exchangers • Many many more…

Slide 18

Slide 18 text

Other APIs • CLI: https://github.com/WebAssembly/wasi-cli • Random: https://github.com/WebAssembly/wasi-random • Clocks: https://github.com/WebAssembly/wasi-clocks

Slide 19

Slide 19 text

Great! Now how can we make it type-safety?

Slide 20

Slide 20 text

WASM Interface Type (WIT) • WIT is an Interface Description Language (IDL) to describe the imports and exports of a module. • It is easy to read and write and provides the foundational basis for producing modules from guest languages (the one you use to create the module) as well as consuming modules in host languages (the one where you use the module) • WIT have two main concepts: interfaces and worlds.

Slide 21

Slide 21 text

WIT: Interfaces • An interface is a named set of types and functions, enclosed in braces. • An interface can reuse types declared in another interface via a use directive interface types { type dimension = u32; record point { x: dimension, y: dimension, } } interface canvas { use types.{dimension, point}; type canvas-id = u64; draw-line: func(canvas: canvas-id, from: point, to: point, thickness: dimension); }

Slide 22

Slide 22 text

WIT: Worlds • A world describes a set of imports and exports for the host to know the full type de f inition, enclosed in braces. • Describes the contracts of the module. interface printer { print: func(text: string); } interface error-reporter { report-error: func(error-message: string); } world multi-function-device { // The module implements the `printer` interface export printer; // The module implements the `scan` function export scan: func() -> list; // The module needs to be supplied with an `error-reporter` import error-reporter; }

Slide 23

Slide 23 text

WIT Core Module. Our main code. Quick Recap ~ WASM Runtimes Server-side Implementation System’s APIs Interfaces to extend capabilities Type de f inition of contracts How do we unify them?

Slide 24

Slide 24 text

✨ Introducing: Component Model ✨

Slide 25

Slide 25 text

WASM: Component Model • Components are portable, interoperable WebAssembly binaries (.wasm f iles) that implement stateless logic. • Components may be compiled from a variety of languages including Rust, Go, Python, JavaScript, and more. • Because components can be compiled from many di ff erent languages and then interact with one another, they enable developers to break down language silos and utilize libraries and tooling in new ways. The component model leverage WASM, WASI and WIT all together.

Slide 26

Slide 26 text

Features • Portable: Because WebAssembly binaries execute against a virtual instruction set architecture (essentially a tiny VM), they are agnostic to architecture and operating system kernel. They are also very small compared to containers, so they can easily run in embedded devices. • Interoperable: Components can interact with one another over high-level APIs regardless of their respective languages of origin, so that a component written in Rust can utilize the functionality of a library from Go. • Composable: Multiple components can be combined into a single binary. This enables developers to build applications as if with lego bricks, satisfying dependencies with other components as needed.

Slide 27

Slide 27 text

Why “components”? We already have modules…

Slide 28

Slide 28 text

• A module corresponds to a single .wasm f ile, with functions, memory, imports and exports, and so on. These "core" modules can run in the browser, or via a separate runtime as we have seen. • Core modules are, however, limited in how they expose their functionality to the outside world and return only a small number of core WASM types (essentially only integers and f loating-point numbers) • Richer types, such as strings, lists, records (a.k.a. structs), etc. have to be represented in terms of integers and f loating point numbers, for example by the use of pointers and o ff sets. • For WASM modules to interoperate between them, there needs to be an agreed- upon way for exposing those richer types across module boundaries.

Slide 29

Slide 29 text

• In the component model, these type de f initions are written in a language called WIT (WASM Interface Type). • A WASM component is thus a wrapper around a core module that speci f ies its imports and exports using WIT.

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

Example Let’s build a simple component to make API requests

Slide 33

Slide 33 text

npm install @bytecodealliance/jco

Slide 34

Slide 34 text

Creating the WIT. • We are going to create a f ile called pokemon-http- client.wit. • Inside the f ile we de f ine: • The world we are going to export: pokemon-http-client • The type of Pokemon. • The function we are going to export: get-by-name

Slide 35

Slide 35 text

Making the code. Fetch, is being provided by ComponentizeJS in the runtime

Slide 36

Slide 36 text

npx jco componentize pokemon-http-client.js —wit pokemon-http-client.wit -o pokemon-http-client.wasm

Slide 37

Slide 37 text

Now we have our component created :D

Slide 38

Slide 38 text

Let’s test it out. JCo allow us to also transpile WASM to ESM.

Slide 39

Slide 39 text

npx jco transpile pokemon-http- client.wasm -o wasm

Slide 40

Slide 40 text

If you notice… is returning only the speci f ied f ields on the WIT. Even though, the API retrieves more f ields :)

Slide 41

Slide 41 text

Now we can easily create components that can be reused anywhere!

Slide 42

Slide 42 text

Key Takeaways • WebAssembly is not only for browsers anymore. • Write once, run anywhere—WASM modules can run across platforms without modi f ication. • Assemble applications by combining reusable components, much like LEGO bricks. • WASI allow us to extend the capabilities of our WASM modules. • Strong security is under a sandboxed and a capability-based environment. • The sky is not the limit.

Slide 43

Slide 43 text

Fun sharing ~ webvm.io

Slide 44

Slide 44 text

Happy Coding! :)