Open8
go-zeroを学ぶ5
client コードについて調べる
API ファイルからクライアントコードを生成してくれるらしいのでどんなコードが出力されるか確認
おさらい
コード生成に使えるコマンドは、goctl api
生成できる言語は、 Java, Kotlin, dart, TypeScript
っぽい。
まずは、TypeScript のコードから生成してみる。
使うのは、Getting Started で作った order.apiを使う
goctl api ts -h
Generate ts files for provided api in api file
Usage:
goctl api ts [flags]
Flags:
--api string The api file
--caller string The web api caller
--dir string The target dir
-h, --help help for ts
--unwrap Unwrap the webapi caller for import
とりあえず、単純にコマンド実行
goctl api ts --api order.api --dir ts
作成されたファイルは、こんな感じ
ts
├── gocliRequest.ts
├── order.ts
└── orderComponents.ts
生成されたファイル
gocliRequest.ts
export type Method =
| 'get'
| 'GET'
| 'delete'
| 'DELETE'
| 'head'
| 'HEAD'
| 'options'
| 'OPTIONS'
| 'post'
| 'POST'
| 'put'
| 'PUT'
| 'patch'
| 'PATCH';
/**
* Parse route parameters for responseType
*/
const reg = /:[a-z|A-Z]+/g;
export function parseParams(url: string): Array<string> {
const ps = url.match(reg);
if (!ps) {
return [];
}
return ps.map((k) => k.replace(/:/, ''));
}
/**
* Generate url and parameters
* @param url
* @param params
*/
export function genUrl(url: string, params: unknown) {
if (!params) {
return url;
}
const ps = parseParams(url);
ps.forEach((k) => {
const reg = new RegExp(`:${k}`);
url = url.replace(reg, params[k]);
});
const path: Array<string> = [];
for (const key of Object.keys(params)) {
if (!ps.find((k) => k === key)) {
path.push(`${key}=${params[key]}`);
}
}
return url + (path.length > 0 ? `?${path.join('&')}` : '');
}
export async function request({
method,
url,
data,
config = {}
}: {
method: Method;
url: string;
data?: unknown;
config?: unknown;
}) {
const response = await fetch(url, {
method: method.toLocaleUpperCase(),
credentials: 'include',
headers: {
'Content-Type': 'application/json'
},
body: data ? JSON.stringify(data) : undefined,
// @ts-ignore
...config
});
return response.json();
}
function api<T>(
method: Method = 'get',
url: string,
req: any,
config?: unknown
): Promise<T> {
if (url.match(/:/) || method.match(/get|delete/i)) {
url = genUrl(url, req.params || req.forms);
}
method = method.toLocaleLowerCase() as Method;
switch (method) {
case 'get':
return request({method: 'get', url, data: req, config});
case 'delete':
return request({method: 'delete', url, data: req, config});
case 'put':
return request({method: 'put', url, data: req, config});
case 'post':
return request({method: 'post', url, data: req, config});
case 'patch':
return request({method: 'patch', url, data: req, config});
default:
return request({method: 'post', url, data: req, config});
}
}
export const webapi = {
get<T>(url: string, req: unknown, config?: unknown): Promise<T> {
return api<T>('get', url, req, config);
},
delete<T>(url: string, req: unknown, config?: unknown): Promise<T> {
return api<T>('delete', url, req, config);
},
put<T>(url: string, req: unknown, config?: unknown): Promise<T> {
return api<T>('get', url, req, config);
},
post<T>(url: string, req: unknown, config?: unknown): Promise<T> {
return api<T>('post', url, req, config);
},
patch<T>(url: string, req: unknown, config?: unknown): Promise<T> {
return api<T>('patch', url, req, config);
}
};
export default webapi
order.ts
import webapi from "./gocliRequest"
import * as components from "./orderComponents"
export * from "./orderComponents"
/**
* @description
* @param params
*/
export function getOrder(params: components.OrderReqParams, id: string) {
return webapi.get<components.OrderReply>(`/api/order/get/${id}`, params)
}
orderComponents.ts
// Code generated by goctl. DO NOT EDIT.
export interface OrderReq {
}
export interface OrderReqParams {
}
export interface OrderReply {
id: string
name: string
}