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
}