Skip to content

Commit 40e359e

Browse files
Himenonhrsh7th
andauthored
feat: provide currying functional api client (#109)
Co-authored-by: hrsh7th <[email protected]>
1 parent c122fd3 commit 40e359e

36 files changed

+5300
-7816
lines changed

README.md

+190-1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,196 @@ const main = () => {
7474
main();
7575
```
7676

77+
### The variation of template code
78+
79+
This library provides three types of templates
80+
81+
```ts
82+
import * as Templates from "@himenon/openapi-typescript-code-generator/templates";
83+
84+
Templates.ClassApiClient.generator;
85+
Templates.FunctionalApiClient.generator;
86+
Templates.CurryingFunctionalApiClient.generator;
87+
```
88+
89+
#### `Templates.ClassApiClient.generator`
90+
91+
We provide a class-based API client. Please inject the API client dependency and use it instead of `constructor`.
92+
93+
```ts
94+
export interface RequestArgs {
95+
httpMethod: HttpMethod;
96+
url: string;
97+
headers: ObjectLike | any;
98+
requestBody?: ObjectLike | any;
99+
requestBodyEncoding?: Record<string, Encoding>;
100+
queryParameters?: QueryParameters | undefined;
101+
}
102+
103+
export interface ApiClient<RequestOption> {
104+
request: <T = SuccessResponses>(requestArgs: RequestArgs, options?: RequestOption) => Promise<T>;
105+
}
106+
107+
export class Client<RequestOption> {
108+
private baseUrl: string;
109+
constructor(private apiClient: ApiClient<RequestOption>, baseUrl: string) {
110+
this.baseUrl = baseUrl.replace(/\/$/, "");
111+
}
112+
113+
public async createPublisherV2<RequestContentType extends RequestContentType$createPublisherV2>(
114+
params: Params$createPublisherV2<RequestContentType>,
115+
option?: RequestOption,
116+
): Promise<Response$createPublisherV2$Status$200["application/json"]> {
117+
const url = this.baseUrl + `/create/v2/publisher/{id}`;
118+
const headers = {
119+
"Content-Type": params.headers["Content-Type"],
120+
Accept: "application/json",
121+
};
122+
const requestEncodings = {
123+
"application/x-www-form-urlencoded": {
124+
color: {
125+
style: "form",
126+
explode: false,
127+
},
128+
},
129+
"application/json": {
130+
color: {
131+
style: "form",
132+
explode: false,
133+
},
134+
},
135+
};
136+
return this.apiClient.request(
137+
{
138+
httpMethod: "POST",
139+
url,
140+
headers,
141+
requestBody: params.requestBody,
142+
requestBodyEncoding: requestEncodings[params.headers["Content-Type"]],
143+
},
144+
option,
145+
);
146+
}
147+
}
148+
```
149+
150+
#### `Templates.FunctionalApiClient.generator`
151+
152+
We also provide a function-based API client that replaces the class-based API client with `createClient`. Please inject the API client dependency and use it.
153+
154+
```ts
155+
export interface RequestArgs {
156+
httpMethod: HttpMethod;
157+
url: string;
158+
headers: ObjectLike | any;
159+
requestBody?: ObjectLike | any;
160+
requestBodyEncoding?: Record<string, Encoding>;
161+
queryParameters?: QueryParameters | undefined;
162+
}
163+
164+
export interface ApiClient<RequestOption> {
165+
request: <T = SuccessResponses>(requestArgs: RequestArgs, options?: RequestOption) => Promise<T>;
166+
}
167+
168+
export const createClient = <RequestOption>(apiClient: ApiClient<RequestOption>, baseUrl: string) => {
169+
const _baseUrl = baseUrl.replace(/\/$/, "");
170+
return {
171+
createPublisherV2: <RequestContentType extends RequestContentType$createPublisherV2>(
172+
params: Params$createPublisherV2<RequestContentType>,
173+
option?: RequestOption,
174+
): Promise<Response$createPublisherV2$Status$200["application/json"]> => {
175+
const url = _baseUrl + `/create/v2/publisher/{id}`;
176+
const headers = {
177+
"Content-Type": params.headers["Content-Type"],
178+
Accept: "application/json",
179+
};
180+
const requestEncodings = {
181+
"application/x-www-form-urlencoded": {
182+
color: {
183+
style: "form",
184+
explode: false,
185+
},
186+
},
187+
"application/json": {
188+
color: {
189+
style: "form",
190+
explode: false,
191+
},
192+
},
193+
};
194+
return apiClient.request(
195+
{
196+
httpMethod: "POST",
197+
url,
198+
headers,
199+
requestBody: params.requestBody,
200+
requestBodyEncoding: requestEncodings[params.headers["Content-Type"]],
201+
},
202+
option,
203+
);
204+
},
205+
};
206+
};
207+
```
208+
209+
#### `Templates.CurryingFunctionalApiClient.generator`
210+
211+
**Tree shaking support**
212+
213+
We also provide a curried function-based API client that requires injection of API client for each `operationId`. The first function argument demands `ApiClient` while the second function argument demands `RequestArgs`. The `ApiClient` interface is different from the others, as it requires `uri` as an argument.
214+
215+
This is designed for use cases that utilize **tree shaking**.
216+
217+
```ts
218+
export interface RequestArgs {
219+
httpMethod: HttpMethod;
220+
uri: string; // <------------------ Note that the uri
221+
headers: ObjectLike | any;
222+
requestBody?: ObjectLike | any;
223+
requestBodyEncoding?: Record<string, Encoding>;
224+
queryParameters?: QueryParameters | undefined;
225+
}
226+
export interface ApiClient<RequestOption> {
227+
request: <T = SuccessResponses>(requestArgs: RequestArgs, options?: RequestOption) => Promise<T>;
228+
}
229+
export const createPublisherV2 =
230+
<RequestOption>(apiClient: ApiClient<RequestOption>) =>
231+
<RequestContentType extends RequestContentType$createPublisherV2>(
232+
params: Params$createPublisherV2<RequestContentType>,
233+
option?: RequestOption,
234+
): Promise<Response$createPublisherV2$Status$200["application/json"]> => {
235+
const uri = `/create/v2/publisher/{id}`;
236+
const headers = {
237+
"Content-Type": params.headers["Content-Type"],
238+
Accept: "application/json",
239+
};
240+
const requestEncodings = {
241+
"application/x-www-form-urlencoded": {
242+
color: {
243+
style: "form",
244+
explode: false,
245+
},
246+
},
247+
"application/json": {
248+
color: {
249+
style: "form",
250+
explode: false,
251+
},
252+
},
253+
};
254+
return apiClient.request(
255+
{
256+
httpMethod: "POST",
257+
uri,
258+
headers,
259+
requestBody: params.requestBody,
260+
requestBodyEncoding: requestEncodings[params.headers["Content-Type"]],
261+
},
262+
option,
263+
);
264+
};
265+
```
266+
77267
### Split the type definition file and the API Client implementation
78268

79269
```ts
@@ -400,4 +590,3 @@ TypeScript AST
400590
Validation Design
401591

402592
- Copyright (c) 2018 Kogo Software LLC - [https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-schema-validator#readme](openapi-schema-validator)
403-

0 commit comments

Comments
 (0)