0.4.2 • Published 3 years ago

restful-bridge v0.4.2

Weekly downloads
4
License
ISC
Repository
github
Last release
3 years ago

restful-bridge

Create matching REST methods for client and server, strongly typed and without duplication.

usage

In a common file required by both the server and client (e.g. routes.ts), create an instance of the RestfulBridge class

import { RestfulBridge } from 'restful-bridge';

const bridge = new RestfulBridge({
    hostname: "site.com",
	port: 5060,
    apiPrefix: "/api/v2",
});

Calls to the createRoute method return an array of two elements: a function that makes the request, and a function that adds the route to an express server. The types for request parameters and response (probably JSON objects) are inferred from the server function.

export const [fetchThing, addThingRoute] = bridge.createRoute(
	'GET',
	'/gimme',
	params => { result: 'here: ' + params.thing },
);

You can also enforce the types by providing them to the createRoute method, as in bridge.createRoute<{ thing: string }, { result: string }>( ....

The client can import and use the fetcher as a stand-alone function:

// client.ts
import { fetchThing } from './routes.ts'
const response = await fetchThing({ thing: 'foo' });

The server must create its own express app (although this package does include a convenience function createExpressApp), and apply the route-adding function to it. That function returns the bridge options, so we can for example access the port number.

// server.ts
import { addFetchRoute } from './routes.ts'
const app = createExpressApp();
const options = addThingRoute(app);
app.listen(options.port);

routes.ts can also export an initializer that adds all the routes creates, and listens at the correct port.

export const initializeServer = bridge.getServerInitializer()

then server.ts becomes:

import { initializeServer } from './routes.ts'
const app = createExpressApp();
initializeServer(app);

preventing browser from loading server code

If the client runs in a browser, we might have a problem because the server code will end up getting required via the common file (see above). You can do a conditional require, but if you're using Typescript you won't get the types, unless you use a trick like this (adapted from http://ideasintosoftware.com/typescript-conditional-imports/)

import { isBrowser } from 'browser-or-node';

import * as serverOnlyModule from './server';
let serverOnly = (null as unknown) as typeof serverOnlyModule;
if (!isBrowser) serverOnly = require('./server');
0.4.1

3 years ago

0.4.0

3 years ago

0.4.2

3 years ago

0.3.8

3 years ago

0.3.7

3 years ago

0.3.6

3 years ago

0.3.5

4 years ago

0.3.4

4 years ago

0.3.2

4 years ago

0.3.3

4 years ago

0.3.1

4 years ago

0.3.0

4 years ago

0.3.0-beta.5

4 years ago

0.3.0-beta.4

4 years ago

0.3.0-beta.3

4 years ago

0.3.0-beta.2

4 years ago

0.3.0-beta.1

4 years ago

0.3.0-beta.0

4 years ago

0.2.6

4 years ago

0.2.5

4 years ago

0.2.3

4 years ago

0.2.2

4 years ago

0.2.4

4 years ago

0.2.1

4 years ago

0.2.0

4 years ago

0.1.3

4 years ago

0.1.2

4 years ago

0.1.1

4 years ago

0.1.0

4 years ago