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






What is an API?

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
😌
🥴
- Client & server tightly coupled
- Having to use the same language
- Need to learn all the procedure names
- Having to use multi-threaded servers
- Parameters marshalling
- Exception handling
Problems with RPC
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
- Complexity
- Steep learning curve
- Mapping problems
- Name confused with a poisonous snake
Problems with 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>🔐 ✈️
- Heavy, requires more bandwidth
- POST = no cache on HTTP layer
- Tightly coupled with server
- Inflexible
Problems with SOAP
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"
- Over fetching
- Big payloads
- n+1 problem
- Limiting constraints
- No end-to-end typesafety
Problems with 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

- Same POST-caching problem as in SOAP
- You have to generate types
- If you use tools like Hasura,
 you push a lot of domain logic to frontend
- Otherwise — boilerplate!
Problems with GraphQL
at least until stuff like Max Stoiber's GraphQL CDN popped up
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
- 2,521
 
   
   
  