simple guide to start with `ts-endpoint`
Other than plain static types definitions, when you define an Endpoint you also want it to be able to validate, serialize and deserialize HTTP payloads into runtime values that are easy to handle in your source code.
In ts-endpoint this power is encapsulated in the Codec interface:
export interface Codec<E, A, B> {
encode: (b: B) => A;
decode: (b: unknown) => Either<E, B>;
}
Fur our purposes, a Codec is a data structure that knows how to:
encodea runtime value into a valid transport layer formatdecodea value coming from the transport layer into a valid runtime value (or an error in case the value is not well-formatted).
A valid Endpoint will use a specific Codec to parse both its Input and Output runtime values:
(N.B.: in the following examples we use io-ts library to create the codecs but feel free to define your own as long as they follow the Codec interface)
import * as t from 'io-ts';
import { Endpoint } from 'ts-endpoint';
const User = t.type({
id: t.number,
name: t.string,
surname: t.string,
age: t.number
})
export const getUser = Endpoint({
Input: {
Params: t.type({ id: NumberFromString }),
},
Method: 'GET',
getPath: ({ id }) => `user/${id}`,
Output: t.type({ user: User }),
});
const createUser = Endpoint({
Input: {
Body: t.strict({
name: t.string,
surname: t.string,
age: t.number,
}),
},
Method: 'POST',
getPath: () => 'users',
Output: t.strict({ id: t.string }),
});