@@ -6,9 +6,75 @@ Tiny, isomorphic TypeScript framework to build "call action" APIs.
66
77` npm i @webcarrot/api `
88
9+ ## General
10+
11+ This library provides generic TypeScript interfaces plus simple implementations / helpers for node and browsers enviroment.
12+
13+ ``` typescript
14+ // interfaces - the essence
15+ import { ApiResolver , ActionFunction } from " @webcarrot/api" ;
16+ // implementations / helpers
17+ import { makeApi as nodeMakeApi } from " @webcarrot/api/node" ;
18+ import { makeApi as browserMakeApi } from " @webcarrot/api/browser" ;
19+
20+ type ActionContext = { context: string ; zee: number };
21+
22+ const action: ActionFunction <
23+ { payload: string ; foo: number },
24+ { output: string ; bar: number },
25+ ActionContext
26+ > = async ({ payload , foo }, { context , zee }) => ({
27+ output: ` payload: ${payload } context: ${context } ` ,
28+ bar: foo + zee
29+ });
30+
31+ // Types are build from plain object like:
32+ const actions = {
33+ actionName: action
34+ };
35+
36+ type Api = ApiResolver <typeof actions >;
37+
38+ // cusom implementation
39+ const someCustomApiProvider: Api = (actionName , actionPayload ) => {
40+ // call api function implementation
41+ };
42+
43+ someCustomApiProvider (" actionName" , { payload: " c" , foo: 1 }).then (
44+ ({ output , bar }) => console .log ({ output , bar })
45+ );
46+
47+ // node helper usage
48+ const nodeApiProvider = nodeMakeApi <typeof actions , ActionContext >({
49+ actions ,
50+ context: { context: " z" , zee: 4 }
51+ });
52+
53+ nodeApiProvider (" actionName" , { payload: " n" , foo: 2 }).then (
54+ ({ output , bar }) => console .log ({ output , bar })
55+ );
56+
57+ // browser helper usage
58+ const browserApiProvider = browserMakeApi <typeof actions >({
59+ endpoint: " /api" ,
60+ headers: {
61+ " X-Foo" : " Bar"
62+ }
63+ });
64+
65+ browserApiProvider (" actionName" , { payload: " b" , foo: 3 }).then (
66+ ({ output , bar }) => console .log ({ output , bar })
67+ );
68+ ```
69+
70+ ## TODO
71+
72+ - Allow to define an optional payload.
73+ - Firebase helper.
74+
975## Example code
1076
11- See [ example] ( https://github.com/webcarrot/api/tree/master/example )
77+ See [ example code ] ( https://github.com/webcarrot/api/tree/master/example )
1278
1379Anyway same code:
1480
@@ -34,7 +100,7 @@ export type AppState = {
34100
35101### Node only side
36102
37- #### Hi action (` example/api/hi.ts ` ):
103+ #### Hi action (` example/api/hi.ts ` )
38104
39105``` typescript
40106import { Context as KoaContext } from " koa" ;
@@ -151,7 +217,7 @@ const api = makeApi<ApiData>({
151217
152218### React
153219
154- #### Make context (` example/apiContext.ts ` );
220+ #### Make context (` example/apiContext.ts ` )
155221
156222``` typescript
157223import { makeContext } from " @webcarrot/api/context" ;
@@ -160,7 +226,7 @@ import { ApiData } from "./types";
160226export const Context = makeContext <ApiData >();
161227```
162228
163- #### App (` example/app.tsx ` )
229+ #### React main " App" Component (` example/app.tsx ` )
164230
165231``` typescript
166232import * as React from " react" ;
@@ -184,24 +250,16 @@ const IUseApi = ({ value = "" }) => {
184250 );
185251};
186252
187- export const App = ({
188- api ,
189- hiFromServer = " "
190- }: {
191- api: ApiContextValue ;
192- hiFromServer: string ;
193- }) => {
253+ export const App = ({ api , hi = " " }: { api: ApiContextValue ; hi: string }) => {
194254 return (
195255 < ApiContext .Provider value = {api }>
196- < IUseApi value = {hiFromServer } / >
256+ < IUseApi value = {hi } / >
197257 < / ApiContext .Provider >
198258 );
199259};
200260```
201261
202- #### Server side
203-
204- Render react app on server (` example/node/react.ts ` )
262+ #### Render react app on server (` example/node/react.ts ` )
205263
206264``` typescript
207265import * as React from " react" ;
@@ -237,19 +295,21 @@ export const handler = async (context: KoaContext) => {
237295 <div id="app">${ReactDOM .renderToString (
238296 React .createElement (App , {
239297 api ,
240- hiFromServer: hi
298+ hi
241299 })
242300 )}</div>
243- <script>APP_STATE=${JSON .stringify (APP_STATE )};</script>
301+ <script src="https://unpkg.com/react@16.8.3/umd/react.production.min.js"></script>
302+ <script src="https://unpkg.com/react-dom@16.8.3/umd/react-dom.production.min.js"></script>
303+ <script>window.process={env:{NODE_ENV:"production"}};APP_STATE=${JSON .stringify (
304+ APP_STATE
305+ )};</script>
244306 <script src="/build/react.js" async defer></script>
245307 </body>
246308</html> ` ;
247309};
248310```
249311
250- #### Browser side
251-
252- Render react app in browser (` example/browser/react.ts ` )
312+ #### Render react app in browser (` example/browser/react.ts ` )
253313
254314``` typescript
255315import * as React from " react" ;
@@ -259,12 +319,12 @@ import { ApiData, AppState } from "../types";
259319import { App } from " ../app" ;
260320
261321declare var APP_STATE: AppState ;
262- const appState = APP_STATE ;
322+ const { api : apiConf, hi } = APP_STATE ;
263323
264- const api = makeApi <ApiData >(appState . api );
324+ const api = makeApi <ApiData >(apiConf );
265325
266326ReactDOM .hydrate (
267- React .createElement (App , { api , hiFromServer: appState . hi }),
327+ React .createElement (App , { api , hi }),
268328 document .getElementById (" app" )
269329);
270330```
0 commit comments