@tbd54566975/dwn-proxy-js
v0.0.5
Published
Bidirectional proxy between DWM's <> RESTful
Downloads
88
Readme
DWN Proxy
Making DWN integrations with traditional backend services easy.
⚠️ UNDER DEVELOPMENT ⚠️
dwn-proxy-js
is a bidirectional proxy between Decentralized Web Nodes and your web services.
Design
At it's lightest, this package can act as a network router for DWN Message's. At it's heaviest, this package can be used to selectively abstract DWN-concepts from your web services. You have optionality as to the degree to which you differentiate across the two network interfaces.
Like the dwn-server
, this package is intended to be used server-side, wherein DWN Messages are interfaced with via JSON-RPC (compatible with web5-js
's Agent interface). However, unlike dwn-server
, this package offers a programmatic interface for handling DWN Messages, both inbound and outbound, with the design intent of integrating with traditional backend services.
Usage
In a new directory, run:
npm init -y
npm install @tbd54566975/dwn-proxy-js
Then edit the package.json to have "type":"module"
in it.
Add a file called index.js
with the following contents:
import { DwnProxy, readReq } from '@tbd54566975/dwn-proxy-js';
const isMessageA = (dwnRequest) => dwnRequest.message.descriptor.interface === 'Records' &&
dwnRequest.message.descriptor.method === 'Query' &&
dwnRequest.message.descriptor.filter.schema === 'https://tbd.website/resources/message-a';
const isMessageB = (dwnRequest) => dwnRequest.message.descriptor.interface === 'Records' &&
dwnRequest.message.descriptor.method === 'Write' &&
dwnRequest.message.descriptor.schema === 'https://tbd.website/resources/message-b';
class MyProxy extends DwnProxy {
async handlerA(request) {
// do whatever you want
// ...
// example: maybe process the message using the DWN instance
const { id } = this.options.didState;
await this.dwn.processMessage(id, request.message, request.payload);
}
async handlerB(request) {
// do whatever you want
// ...
// example: maybe forward the request onto your backend
await fetch('/your-backend', {
method: 'POST',
body: JSON.stringify(request)
});
}
async apiC(req, res) {
const body = await readReq(req);
// do whatever you want
// ...
// maybe send the message onto a user
await this.client.send(body.to, body.dwnRecordsWrite, JSON.stringify(body.data));
}
async apiD(req, res) {
const body = await readReq(req);
// do whatever you want
// ...
}
// overriding the default DwnProxy.listen()
async listen(port) {
await super.listen(port);
// wire-up your dwn handlers
this.addHandler(isMessageA, this.handlerA);
this.addHandler(isMessageB, this.handlerB);
// wire-up your server handlers
this.server.api.post('/handler-c', this.apiC);
this.server.api.post('/handler-d', this.apiD);
}
}
const PORT = 8080;
const proxy = new MyProxy({});
await proxy.listen(PORT);
node index.js
And you have a proxy running!
new DwnProxy(options)
options
:- (optional)
serviceEndpoint
- (optional)
didState
- (optional)
DwnProxy.listen(port)
Start a JSON-RPC server, hosting an HTTP server at the given port
.
- (required)
port
: number
DwnProxy.addHandler(match, handler)
Add a handler for inbound DWN Messages.
const isMyMessage = req =>
req.message.descriptor.interface === 'Records' &&
req.message.descriptor.method === 'Write' &&
req.message.descriptor.schema === 'https://your-schema/file.json'
proxy.addHandler(
isMyMessage,
async req => {
// do whatever you would like with the given DwnRequest
}
)
- (required)
match
:(req: DwnRequest) => boolean
- if evaluated to
true
then usehandler
for the given message
- if evaluated to
- (required)
handler
:(dwnRequest: DwnRequest) => Promise<void | DwnResponse>
- if return type is
void
then the underlyingDwnHttpServer
will calldwn.processMessage()
whereafter it will respond to the client w/ the given result - Else, you can explicitly specify your
DwnResponse
which will not result in a subsequent call todwn.processMessage()
- if return type is
DwnProxy.server.api
Directly interface with the Express server
proxy.server.api.post('/some-outbound-api', async (req, res) => {
// do whatever you would like
res.status(200)
res.end()
})
Project Resources
| Resource | Description | | ------------------------------------------ | ----------------------------------------------------------------------------- | | CODEOWNERS | Outlines the project lead(s) | | CODE_OF_CONDUCT.md | Expected behavior for project contributors, promoting a welcoming environment | | CONTRIBUTING.md | Developer guide to build, test, run, access CI, chat, discuss, file issues | | GOVERNANCE.md | Project governance | | LICENSE | Apache License, Version 2.0 |