Making REST APIs Typesafe With feTS
Aleksandra Sikora, @aleksandrasays
whoami
- open-source engineer @
- π§ββοΈ
- org of WrocΕaw
previously
- .js maintainer
- cc tech lead
π¦ @aleksandrasays
π @beerose
π https://aleksandra.codes






Why are we talking about APIs?
Server & Client
Server & Client
π₯΄
Server & Client
π
API Layer Problems
Boilerplate
Lost typesafety
Repetitive error handling

TYPE-SAFE
TYPE-SAFE

RPC
1981

What is RPC?
// one-computer.js function welcome(name) { return `Hello, ${name}!` } const greeting = welcome("Helsinki!") // ^ "Hello, Helsinki!"
// server.js function welcome(name) { return `Hello, ${name}!` } startImaginaryServer({ welcome })
// client.js const greeting = await fetch( `https://aleksandra.says/rpc/welcome`, { body: JSON.stringify("Helsinki") } )
What is RPC?
calling remote procedures as if they were local
π
π₯΄
RPC -> non-agnostic
RPC -> non-agnostic
βββββ
now we're looking for sth
CORBA
1991
NOT ΓORBA


AND NOT COBRA
module Finance { typedef sequence<string> StringSeq; struct AccountDetails { string name; StringSeq address; long account_number; double current_balance; }; exception insufficientFunds { }; interface Account { void deposit(in double amount); void withdraw(in double amount) raises(insufficientFunds); readonly attribute AccountDetails details; }; };
IDL

Developer trying to learn Corba
CORBA -> complex
simple
- -
CORBA -> complex
now we need
SOAP
1998
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/" soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding"> <soap:Body> <m:GetUserResponse> <m:Username>Tony Stark</m:Username> </m:GetUserResponse> </soap:Body> </soap:Envelope>
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> <soap:Header> </soap:Header> <soap:Body> <m:GetUser> <m:UserId>123</m:UserId> </m:GetUser> </soap:Body> </soap:Envelope>
π βοΈ
SOAP -> heavy
light
-
SOAP -> heavy
now we're looking for sth
REST
2000
When the web started to change
Can request and update resources
Exposes resources


Operation | RPC | REST |
---|---|---|
Login | POST /login | POST /sessions |
Logout | POST /logout | DELETE /sessions |
Get user by id | GET /getUser?id=123 | GET /users/123 |
Get user's todo items | GET /getTodos?userId=123 | GET /users/123/todos |
Add new todo item | POST /addTodo | POST users/123/todos |
Update todo item | POST /updateTodo | PUT /todos/1 |
Delete todo item | POST /deteteTodo | DELETE /todos/1 |
RPC vs. REST
JSON-RPC
RESTful
"REST"
REST -> inflexible
-
REST -> inflexible
time for something
GraphQL
2012
REST API
GraphQL API
API
App
GET users/
GET tasks/
GET tags/
API
App
POST graphql/
Body:
{ "query": "query { users {...} }" }
vs
Client controls the data it gets
User 1
Task 1
Task 2
Tag 1
Tag 2
query {
user(id: 1) {
name
tasks {
name
status
tags {
id
}
}
}
}
name
surname
age
status
name
priority
name
priority
status
description
id
Tag 3
id
description
id
description
id

GraphQL -> extra work & type-safety
-
GraphQL -> extra work & type-safety
-
-
for free and out of the box
RPC
2020
Revisiting the original promise of RPC
1981


Fullstack TypeScript app
Fullstack TypeScript app
Fullstack TypeScript app
tRPC query & mutation procedures
Remix loader pattern
React Server Components
Qwik City
Blitz RPC query & mutation resolvers
pRPC
Source: https://twitter.com/markdalgleish/status/1256800146118959109

?
2023
Cool, but...
again, non-agnostic
once again, we'd like something agnostic
type-safety is a must




feTS
DEMO
π Type-safety out of the box
π No runtime overhead
π IDE features
https://the-guild.dev/openapi/fets

Summary


APIs


Thank you!
@aleksandrasays
www.aleksandra.codes

OLX Meetup: Typesafe REST with feTS
By Aleksandra Sikora
OLX Meetup: Typesafe REST with feTS
- 1,482