Skip to main content

farrow-api

farrow-api: Schema-based Api builder

Setup#

Install via npm or yarn

# via npm
npm install --save farrow-api
# via yarn
yarn add farrow-api

Usage#

Writing farrow-api is just like typing in a higher-order way, we define a api-type via farrow-schema. And then use farrow-api-server to attach api to a http server.

import { Api } from 'farrow-api'
import { Int, List, ObjectType, Type, TypeOf } from 'farrow-schema'
/**
* define Todo
*/
export class Todo extends ObjectType {
id = {
description: `Todo id`,
[Type]: Int,
}
content = {
description: 'Todo content',
[Type]: String,
}
completed = {
description: 'Todo status',
[Type]: Boolean,
}
}
// infer the type of Todo
export type TodoType = TypeOf<Todo>
// define Todos
export const Todos = List(Todo)
// define AddTodoInput
export class AddTodoInput extends ObjectType {
content = {
description: 'a content of todo for creating',
[Type]: String,
}
}
// define AddTodoInput
export class AddTodoOutput extends ObjectType {
todos = {
description: 'Todo list',
[Type]: Todos,
}
}
// define an api via input schema and output schema
export const addTodo = Api(
{
description: 'add todo',
input: AddTodoInput,
output: AddTodoOutput,
},
(input) => {
// impl addTodo
return {
todos: [],
}
},
)
// define RemoveTodoInput
export class RemoveTodoInput extends ObjectType {
id = {
description: 'Todo id for removing',
[Type]: Int,
}
}
// define RemoveTodoOuput
export class RemoveTodoOuput extends ObjectType {
todos = {
description: 'Remain todo list',
[Type]: Todos,
}
}
// define an api without impl
export const removeTodo = Api({
description: 'remove todo',
input: RemoveTodoInput,
output: RemoveTodoOuput,
})
// an api is also a pipeline
removeTodo.use((input, next) => {
return next(input)
})
// impl remove todo via pipeline.use
removeTodo.use((input) => {
state.todos = state.todos.filter((todo) => todo.id !== input.id)
return {
todos: state.todos,
}
})
// combine all api to an object/entries
export const entries = {
addTodo,
removeTodo,
}

API#

/**
* create Api via ApiDefinition
*/
const Api: (definition: ApiDefinition, impl?: ApiImpl<T> | undefined) => ApiType<T>
/**
* ApiDefinition
*/
export type ApiDefinition = {
/**
* input schema of api
*/
input: SchemaCtorInput
/**
* output schema of api
*/
output: SchemaCtorInput
/**
* description of api
*/
description?: string
/**
* depcreated info of api if needed
*/
deprecated?: string
}