Skip to content

Commit b050ac8

Browse files
committed
First crack at concepts
1 parent 206d0f3 commit b050ac8

File tree

5 files changed

+66
-0
lines changed

5 files changed

+66
-0
lines changed

component-model/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
book

component-model/book.toml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[book]
2+
authors = ["itowlson"]
3+
language = "en"
4+
multilingual = false
5+
src = "src"
6+
title = "The WebAssembly Component Model"

component-model/src/SUMMARY.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Summary
2+
3+
- [What is a Component?](./what-is-a-component.md)
4+
- [Concepts](./concepts.md)

component-model/src/concepts.md

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Concepts
2+
3+
The Component Model is predicated on a small number of fundamental concepts:
4+
5+
## Interfaces
6+
7+
An **interface** describes a single focused, composable contract, through which components can interact with each other and with hosts. Interfaces describe the types and functions used to carry out that interaction.
8+
9+
* A "receive HTTP requests" interface might have only a single "handle request" function, but contain types representing incoming requests, outgoing responses, HTTP methods and headers, and so on.
10+
* A "wall clock" interface might have two functions, one to get the current time and one to get the granularity of the timer. It would also include a type to represent an instant in time.
11+
12+
## Canonical ABI
13+
14+
An ABI is an **application binary interface** - an agreement on how to pass data around in a binary format. ABIs are specifically concerned with data layout at the bits-and-bytes level. For example, an ABI might define how integers are represented (big-endian or little-endian?), how strings are represented (pointer to null-terminated character sequence or length-prefixd? UTF-8 or UTF-16 encoded?), and how composite types are represented (the offsets of each field from the start of the structure).
15+
16+
The component model defines a **canonical ABI** - an ABI to which all components adhere. This guarantees that components can talk to each other without confusion, even if they are built in different languages. Internally, a C component might represent strings in a quite different way from a Rust component, but the canonical ABI provides a format for them to pass strings across the boundary between them.
17+
18+
## Worlds
19+
20+
A **world** is a higher-level contract that describes a component's capabilities and needs. In a sense, a world _defines_ a component - it says what interfaces the component exposes for other code to call, and what interfaces the component depends on - but it defines only the surface of a component, not the internal behaviour.
21+
22+
A world is composed of interfaces, but each interface is _directional_ - it indicates whether the interface is available for outside code to call, or outside code must fulfil the interface for the component to call. These interfaces strictly bounds the component. A component cannot interact with anything outside itself except by having its exports called, or by calling its imports. This provides very strong sandboxing: for example, if a component does not have an import for a secret store, then it _cannot_ access that secret store, even if the store is running in the same process.
23+
24+
For a component to run, its imports must be fulfilled, by a host or by other components. Connecting up one component's imports to another component's matching exports is called _composition_.
25+
26+
* A (trivial) "HTTP proxy" world would export a "receive HTTP requests" interface, and import a "send HTTP requests" interface. A host, or another component, would call the exported "receive" interface, passing an HTTP request; the component would forward it on via the imported "send" interface. To be a _useful_ proxy, the component would also need to import interfaces such as I/O and clock time - without those imports the component could not perform, for example, caching.
27+
28+
## Components
29+
30+
Physically, a **component** is a specially formatted WebAssembly file. Internally, the component could include multiple traditional WebAssembly modules, and sub-components, composed via their imports and exports.
31+
32+
The external interface of a component - its imports and exports - corresponds to a world. The component, however, defines behaviour and internal state.
33+
34+
## Packages
35+
36+
A **package** is a set of one or more WIT (Wasm Interface Type) files containing a related set of interfaces and worlds. WIT is an IDL (interface definition language) for Wasm. Packages provide a way for worlds and interfaces to refer to each other, and thus for an ecosystem of components to share common definitions.
37+
38+
A package is not a world. It's a way of grouping related interfaces and worlds together for ease of discovery and reference, more like a namespace.
39+
40+
* The WebAssembly System Interface (WASI) defines a number of packages, including one named `wasi:clocks`. Our HTTP proxy world could import the `wall-clock` interface from the `wasi:clocks` package, rather than having to define a custom clock interface.
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# What is a Component?
2+
3+
If you've tried out WebAssembly, you'll be familiar with the concept of a _module_. Roughly speaking, a module corresponds to a single `.wasm` file, with functions, types, memory, imports and exports, and so on. These modules can run in the browser, or via a separate runtime such as Wasmtime or Wamr. A module is what you get by default when you compile a program written in Rust, C, Go or whatever to WebAssembly.
4+
5+
Modules are, however, limited to describing themselves in terms of core WebAssembly types - integers and floating-point numbers. Just as in native assembly code, richer types, such as strings or records (structs), have to be represented in terms of integers and floating point numbers, for example by the use of pointers and offsets. And just as in native code, those representations are not interchangeable. A string in C might be represented entirely differently from a string in Rust, or a string in JavaScript.
6+
7+
For Wasm modules to interoperate, therefore, there needs to be an agreed-upon way of defining those richer types, and an agreed-upon way of expressing them at module boundaries.
8+
9+
In the component model, these definitions are written in a language called WIT (Wasm Interface Type), and the way they translate into bits and bytes is called the Canonical ABI (Application Binary Interface).
10+
11+
Such an agreement adds a new dimension to Wasm portability. Not only are modules portable across architectures and operating systems, but they are now portable across languages. A Go module can communicate directly and safely with a C or Rust module. It need not even know which language another module was written in - it needs only the module interface, expressed in WIT. Modules can even be linked into larger graphs, with one module satisfying another's dependencies, and deployed as units.
12+
13+
Combined with Wasm's strong sandboxing, this opens the door to yet further benefits. By expressing higher-level semantics than integers and floats, it becomes possible to statically analyse and reason about a module's behaviour - to enforce and guarantee properties just by looking at the surface of the module. The relationships between a graph of modules can be analysed, for example to verify that a module containing business logic has no access to a module containing personally identifiable information.
14+
15+
This guide doesn't try to formally specify what a component _is_. Physically, components are Wasm modules, such as `.wasm` files, with a specific internal format. Logically, components are containers for modules - or other components - which express their interfaces and dependencies via WIT and the Canonical ABI. Conceptually, components are self-describing units of code.

0 commit comments

Comments
 (0)