Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/rawrmaan/restyped
End-to-end typing for REST APIs with TypeScript
https://github.com/rawrmaan/restyped
axios express nodejs rest rest-api typescript
Last synced: about 2 months ago
JSON representation
End-to-end typing for REST APIs with TypeScript
- Host: GitHub
- URL: https://github.com/rawrmaan/restyped
- Owner: rawrmaan
- License: mit
- Created: 2017-10-05T23:40:24.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2018-08-02T21:30:16.000Z (over 6 years ago)
- Last Synced: 2024-10-01T07:29:39.288Z (3 months ago)
- Topics: axios, express, nodejs, rest, rest-api, typescript
- Language: TypeScript
- Homepage:
- Size: 49.8 KB
- Stars: 314
- Watchers: 9
- Forks: 10
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-typescript - restyped - End-to-end typing for REST APIs with TypeScript (Table of Contents / HTTP)
README
End-to-end typing for REST APIs with TypeScript## Motivation
[Read the blog post](https://blog.falcross.com/introducing-restyped-end-to-end-typing-for-rest-apis-with-typescript/)
## Benefits
- **End-to-end typing.** Share request and response types between your client
and server for ease of use and peace of mind.
- **Unopinionated.** Works with any new or existing REST API.
- **Universal.** Can support any server framework or REST client.
- **~~Lightweight~~ Weightless.** Client and server implementations add no runtime code--It's Just Types™.
- **Use existing syntax.** Declare and call your routes the same way you always
have.
- **Great for private APIs.** Keep API clients across your organization in sync
with the latest changes.
- **Great for public APIs.** Create a RESTyped definition so TypeScript users
can consume your API fully typed.
- **Easy to learn and use.** Start using RESTyped in less than one minute per
route.## How to use it
RESTyped is a specification (see below). You can use these server and client
packages along with a RESTyped defintion file to declare and consume APIs in a
type-safe manner:- [restyped-axios](https://github.com/rawrmaan/restyped-axios) - Client wrapper
for Axios to consume RESTyped APIs
- [restyped-express-async](https://github.com/rawrmaan/restyped-express-async) -
Server wrapper for express to deliver RESTyped APIs using promises
- [restyped-hapi](https://github.com/jbpionnier/restyped-hapi) - Server wrapper for Hapi.js routes to deliver RESTyped APIsYou can help make RESTyped more useful by implementing support in your favorite
server framework or HTTP client!**_RESTyped requires TypeScript 2.4 or higher._**
## Specification
It's very easy to get started with RESTyped. Just follow a few steps to type
your existing API or create a new typed API:- Your API should be defined in one interface, exported as `{my_api_name}API`
from a file ending in `.d.ts`
- Each route is a top level key in the interface. You should exclude any
prefixes like `/api/`.
- Each route can have up to one key per valid HTTP method:
- `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD` or `OPTIONS`
- Each HTTP method can have one or more of the following keys:
- `params`: Route params in the URL (e.g. `/users/:id` would have `id` as a
param)
- `query`: Query string params, typically used in `GET` requests (e.g.
`req.query` in express)
- `body`: JSON body object (e.g. `req.body` in express or `data` object in an
axios request)
- `response`: The route's JSON responseAlso see the spec implementation [base defintions](/spec/index.d.ts).
Example: `my-social-api.d.ts`
```typescript
interface User {
// Model inteface--could be imported from another file
email: string
name: string
gender: 'Male' | 'Female' | 'Other'
}export interface MySocialAPI {
'/users': {
// Route name (without prefix, if you have one)
GET: {
// Any valid HTTP method
query: {
// Query string params (e.g. /me?includeProfilePics=true)
includeProfilePics?: boolean
}
response: User[] // JSON response
}
}'/user/:id/send-message': {
POST: {
params: {
// Inline route params
id: string
}
body: {
// JSON request body
message: string
}
response: {
// JSON response
success: boolean
}
}
}
}
```## Full-Stack Example
### 1. Define your API
```typescript
export interface FoodDeliveryAPI {
'/me/orders': {
POST: {
body: {
foodItemIds: number[]
address: string
paymentMethod: 'card' | 'cash'
}
response: {
success: boolean
eta?: string
}
}
}// ...other routes...
}
```### 2. Declare the API via express
```typescript
import RestypedRouter from 'restyped-express-async'
import { FoodDeliveryAPI } from './food-delivery-api'
import * as express from 'express'const app = express()
const apiRouter = express.Router()
app.use('/api', apiRouter)const router = RestypedRouter(apiRouter)
router.post('/me/orders', async req => {
// Will not compile if you attempt to access an invalid body property
const {
foodItemIds, // number[]
address, // string
paymentMethod // 'card' | 'cash'
} = req.bodyconst success = await OrderModel.order(foodItemIds, address, paymentMethod)
// Will not compile if returned value is not of type {success: boolean}
return { success }
})
```### 3. Consume the API via axios
```typescript
import axios from 'restyped-axios'
import { FoodDeliveryAPI } from './food-delivery-api'const api = axios.create({
baseURL: 'https://fooddelivery.com/api/'
})async function order() {
// Will not compile if you pass incorrectly typed body params
const res = await api.post('/me/orders', {
foodItemIds: [142, 788],
address: '1601 Market St, Phiadelphia, PA 19103',
paymentMethod: 'cash'
})// TypeScript knows that res.data is of type {success: boolean, eta?: string}
const { success, eta } = res.data
}
```## What RESTyped isn't
- **A replacement for API docs.** A RESTyped spec will help you get the
**routes** and **types** right, but doesn't provide any **context** or
explanation of your API.## Popular APIs to try out
- Giphy API:
[`restyped-giphy-api`](https://github.com/rawrmaan/restyped-giphy-api)