Skip to main content

farrow-api-client

farrow-api-client is an api-client for farrow-api-server

Installation#

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

Usage#

Using farrow to codegen the api-client, and config apiPipeline if needed.

Simply, we can import the file via codegen directly without modification.

If we need to touch request/response, there are two ways.

The first way only affects one url.

// import the apiPipeline from target module
import { apiPipeline } from '../api/todo'
/**
* farrow-api-client is based on farrow-pipeline
* use pipeline.use(middleware) to do something you want
*/
apiPipeline.use(async (request, next) => {
/**
* add extra fileds for post requeset body
*/
let body = {
...request.body,
token: 'abc',
}
/**
* add extra headers for post request
*/
let options: RequestInit = {
headers: {
'x-access-token': 'abc',
},
}
/**
* pass new request to next and await for the response
*/
let response = await next({
...request,
body,
options,
})
// handle the response if needed
return response
})

The second way only affects all urls.

// import the apiPipeline from farrow-api-client
import { apiPipeline } from 'farrow-api-client'
// all request performed via farrow-api-client will come here
// it should be handled carefully
apiPipeline.use(async (request, next) => {
let response = await next(request)
return response
})
/**
* match(string | regexp, middleware)
* match the request url and handle it via farrow-pipeline
* if pass a string, it will be matched by url.endsWith(pattern)
* if pass a regexp, it will be matched by pattern.test(url)
*/
apiPipeline.match('/todo', async (request, next) => {
/**
* add extra fileds for post requeset body
*/
let body = {
...request.body,
token: 'abc',
}
/**
* add extra headers for post request
*/
let options: RequestInit = {
headers: {
'x-access-token': 'abc',
},
}
/**
* pass new request to next and await for the response
*/
let response = await next({
...request,
body,
options,
})
// handle the response if needed
return response
})

Api#

apiPipeline#

export type ApiRequest = {
url: string
body: {
path: string[]
input: JsonType
}
options?: RequestInit
}
export type ApiErrorResponse = {
error: {
message: string
}
}
export type ApiSuccessResponse = {
output: JsonType
}
export type ApiResponse = ApiErrorResponse | ApiSuccessResponse
export type ApiPipeline = AsyncPipeline<ApiRequest, ApiResponse> & {
match(pattern: string | RegExp, middleware: Middleware<ApiRequest, MaybeAsync<ApiResponse>>): void
invoke(url: string, body: ApiRequest['body']): Promise<JsonType>
}
export type ApiPipelineWithUrl = AsyncPipeline<ApiRequest, ApiResponse> & {
invoke(body: ApiRequest['body']): Promise<JsonType>
}