1---
2title: APIs
3description: Every Function and Server returns { fetch, ...rpcs } — schemaless typed calls are the default for internal communication; Effect RPC and Effect HTTP add schemas where data crosses a trust boundary.
4---
5
6Every Function and Server in alchemy returns `{ fetch, ...rpcs }` from its
7[Effectful Constructor](/infrastructure-as-effects/runtime#the-effectful-constructor) —
8you already saw the "return what you expose" half. The `rpcs` are the other
9half: plain functions returning `Effect` or `Stream`, no schema, no
10decorators:
11
12```typescript
13import * as Cloudflare from "alchemy/Cloudflare";
14import * as Effect from "effect/Effect";
15import * as HttpServerResponse from "effect/http/HttpServerResponse";
16
17export default class BindingTargetWorker extends Cloudflare.Worker<BindingTargetWorker>()(
18 "BindingTargetWorker",
19 {
20 main: import.meta.url,
21 },
22 Effect.gen(function* () {
23 return {
24 greet: (name: string) => Effect.succeed(`hello ${name}`),
25 fetch: Effect.gen(function* () {
26 return HttpServerResponse.text("hello from BindingTargetWorker");
27 }),
28 };
29 }),
30) {}
31```
32
33Any other resource that binds this Worker gets a **fully typed client**:
34`yield* target.greet("world")` is an ordinary Effect call, the return type is
35inferred from the class, and serialization is handled automatically. The same
36model holds across every pairing — a Durable Object bound into a Worker, a
37Container called from a Durable Object, a MicroVM called from a Lambda
38Function.
39
40That schemaless path is the **default for internal communication**. Schemas
41enter only when data crosses a **trust boundary** — a web app, an external
42service, anything you don't deploy yourself.
43
44## The three modalities
45
46| Modality | Schema | Per-request cost | Use when | Clients |
47| ----------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
48| [Schemaless RPC](/apis/schemaless) | None | Proxy dispatch + structured clone (native Bindings) or JSON args (fetch transport) + an envelope-tag check — zero validation | Internal service-to-service: Worker → Worker, Worker → Durable Object, Durable Object → Container, Lambda → MicroVM | Any resource that binds the class (MicroVMs connect explicitly via `connectMicrovm`) |
49| [Effect RPC](/apis/effect-rpc) | `RpcGroup` | Wire-frame parse + Schema decode of the payload + handler + Schema encode of the result — mirrored on the client | Data needs sanitizing or crosses a trust boundary (web app, external service) and consumers are Effect/TypeScript | The schema + a reference to the Fetcher — a Binding or just a URL |
50| [Effect HTTP](/apis/effect-http) | `HttpApi` | Same profile as Effect RPC | Same trust-boundary case, but consumers are non-Effect / non-TypeScript | Plain HTTP — real URLs, path params, query strings, headers, content types, `curl` |
51
52## Choosing
53
54Default to **Schemaless RPC for anything internal**. There is no schema to
55write, no runtime checking, and no per-request validation cost — and internal
56callers already get end-to-end types for free, because the client type *is*
57the class you bound.
58
59**Effect RPC and Effect HTTP are for trust boundaries.** They are discouraged
60for internal service-to-service calls: every request pays a Schema decode and
61encode on both sides, which buys you nothing when you control both ends. Reach
62for them when data needs sanitizing — a browser, a partner service, anything
63outside your deploy.
64
65Between the two schema'd modalities the choice is about the **external
66consumer**: an Effect/TypeScript client combines your schema with a Fetcher
67and gets a typed RPC client — use [Effect RPC](/apis/effect-rpc); anyone else
68wants a real HTTP surface they can hit with a plain HTTP client — use
69[Effect HTTP](/apis/effect-http).
70
71The three interoperate on one host: the schema'd modalities build an
72`HttpEffect` returned from `fetch`, so a single Worker or Function can serve
73schemaless methods internally **and** a schema'd surface externally.
74
75## Where next
76
771. [Schemaless RPC](/apis/schemaless) — the internal default: typed clients, Streams, and error propagation with no schema.
782. [Effect RPC](/apis/effect-rpc) — `RpcGroup` schemas, handler Layers, and clients built from the schema + a Fetcher.
793. [Effect HTTP](/apis/effect-http) — the same idea as real REST endpoints for non-Effect consumers.
80
81Then see it wired up in the hubs:
82
83- **Cloudflare** — [Schemaless RPC](/cloudflare/apis/schemaless-rpc), [Effect RPC](/cloudflare/apis/effect-rpc), [Effect HTTP](/cloudflare/apis/effect-http-api)
84- **AWS** — [Schemaless RPC](/aws/apis/schemaless-rpc), [Effect RPC](/aws/apis/effect-rpc), [Effect HTTP](/aws/apis/effect-http-api)