@ api-ts/ 超剂- wrapper
将一个像谱与 superagent编号 :supertest 以创建已选中的 api 客户端.
开始
首先,定义或导入 io-ts-http api spec. (英语). 接下来将使用
本指南:
import * as h from '@api-ts/io-ts-http';
import * as t from 'io-ts';
import { NumberFromString } from 'io-ts-types';
export const Example = t.type({
foo: t.string,
bar: t.number,
});
export const GenericAPIError = t.type({
message: t.string,
});
export const PutExample = h.httpRoute({
path: '/example/{id}',
method: 'PUT',
request: h.httpRequest({
params: {
id: NumberFromString,
},
body: {
example: Example,
},
}),
response: {
ok: Example,
invalidRequest: GenericAPIError,
},
});
export const ExampleAPI = h.apiSpec({
'api.example': {
put: PutExample,
},
});
ExampleAPI 然后可用于为其中任一创建一个类型安全 api 客户端 superagent
或者说 supertest这需要两个步骤: superagent编号 :supertest 举例来说,
然后把它绑在皮克上.
对于 superagent数字 :
import { superagentRequestFactory, buildApiClient } from '@api-ts/superagent-wrapper';
import superagent from 'superagent';
import { ExampleAPI } from './see-the-above-example';
// The api root, in a real project probably coming from a config option
const BASE_URL = 'http://example.com/';
// Step one: wrap `superagent` and the api root
const requestFactory = superagentRequestFactory(superagent, BASE_URL);
// Step two: combine the request factory and imported api spec into an api client
// This is intended to be exported and used
export const apiClient = buildApiClient(requestFactory, ExampleAPI);
对于 supertest 过程几乎完全相同,但 supertest 自己处理
了解根 api url:
import { supertestRequestFactory, buildApiClient } from '@api-ts/superagent-wrapper';
import supertest from 'superagent';
import { ExampleAPI } from './see-the-above-example';
// For the purposes of this guide, say we have an Express app that can be imported from the project.
// See the `supertest` docs for the options it has for instantiation.
import { app } from '../src/index';
const request = supertest(app);
// Step one: wrap the `supertest` request function created above
const requestFactory = superatestRequestFactory(request);
// Step two: combine the request factory and imported api spec into an api client
// This is intended to be exported and used
export const apiClient = buildApiClient(requestFactory, ExampleAPI);
结果 apiClient 然后可以进口到其他地方并使用:
import { apiClient } from './api-client-example';
const doSomething = async () => {
// The `api.example` here comes from the operation in the `ExampleAPI` definition from above
const response = await apiClient['api.example']
// The object passed to this function is type-checked against the request codec
.put({ id: 42, example: { foo: 'hello', bar: 1 } })
// This will use the set of response codecs to decode the response
.decode();
// The two main properties on `response` are `status` and `body`
// If the value of `status` is checked, then TypeScript will infer the correct body type
if (response.status === 200) {
const { foo, bar } = response.body; // We know the correct body type here
} else if (response.status === 400) {
// The body is a GenericAPIError
console.log(response.body.message);
} else {
// In case an unexpected status code comes back, or the response body does not correctly
// decode, we can still access it as an `unknown` type.
if (
response.body &&
typeof response.body === 'object' &&
response.body.hasOwnProperty('message')
) {
console.log(response.body.message);
}
}
};
为方便起见,a decodeExpecting 函数也被添加到请求中。 它接受一个
HTTP 状态代码和扔出,如果响应代码不匹配,或者它不匹配但
响应机构无法解码 .
const expectOk = async () => {
// The `api.example` here comes from the operation in the `ExampleAPI` definition from above
const response = await apiClient['api.example']
// The object passed to this function is type-checked against the request codec
.put({ id: 42, example: { foo: 'hello', bar: 1 } })
// This will use the set of response codecs to decode the response
.decodeExpecting(200);
const { foo, bar } = response.body;
};