New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@pawsteam/ts-jsonrpc-server

Package Overview
Dependencies
Maintainers
3
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@pawsteam/ts-jsonrpc-server - npm Package Compare versions

Comparing version 0.1.2 to 0.2.0

13

package.json
{
"name": "@pawsteam/ts-jsonrpc-server",
"version": "0.1.2",
"version": "0.2.0",
"description": "A framework for easily building JSONRPC simple servers in TS",
"main": "dist/server.js",
"types": "dist/server.d.ts",
"dependencies": {},
"dependencies": {
"amqplib": "^0.5.5",
"reflect-metadata": "^0.1.13"
},
"devDependencies": {

@@ -29,5 +32,7 @@ "@types/jest": "^24.0.25",

"test": "npm run test:units && npm run test:e2e",
"watch:units": "node node_modules/.bin/jest --passWithNoTests --config jest-units.config.js --watch"
"watch": "node node_modules/.bin/jest --passWithNoTests --config jest-units.config.js --watch"
},
"files": ["dist/**/*"],
"files": [
"dist/**/*"
],
"repository": {

@@ -34,0 +39,0 @@ "type": "git",

# Typescript JSONRPC server
This is a very simple & straight forward way of creating JSONRPC serices.
It can also emit events that other services can subscribe to, in order to create an API event-based infrastructure.
## Features
* Input validators
* Input transformers
* Response serializer
## Installation
For MacOS Catalina, please follow [this link](https://github.com/nodejs/node-gyp/blob/master/macOS_Catalina.md)
All the rest, ```npm install```.
All the rest, ```npm install @pawsteam/ts-jsonrpc-server```.
## Basic usage
```typescript
@AppConfigDecorator({
port: 2000,
services: [SomeService],
genericValidators: [
new HeaderExistsValidator('content-type'),
new HeaderValueContainsValidator('user-agent', 'Mozilla/5.0')
]
})
class AppMain {
}
@ServiceDecorator({path: '/hotels'})
class HotelsService {
listHotels(): Promise<any> {
return new Promise((resolve, reject) => {
// fetch data.then((data) => {
resolve(data);
// })
})
}
}
```
Later, when running this app, you can make a JSONRPC request to the methods exposed by this endpoint:
```typescript
request({
method: 'post',
url: 'http://localhost:2000/hotels'
json: {
id: Math.round(Math.random() * 1000),
jsonrpc: '2.0',
method: 'listHotels',
params: {}
}
}, (error, response, body) => {
expect(body).toMatchObject({
id: ...,
jsonrpc: '2.0',
result: {data}
})
})
```
## The Framework
The framework is aimed at making life easier when writing JSON-RPC servers.
It is Promise-based, so everything will return a promise, except for validators.
It is revolving around stages/hooks in the life of a request:
It is Promise-based, so everything returns a promise, with very few exceptions (validators).
It is based on stages/hooks in the life of a request:
![](docs/Request%20Diagram.svg)
1. Input validators
The life stages of a request can be intercepted with special classes that must implement specific interfaces.
### Input validators
They check the request for required data and types. It's a place to define what parameters are needed for a method to be called.
Any number of Input Validators can be assigned for one method. Generic ones as well;
```
#### Generic validators
Generic validators are set on the app level, and they will be triggered on all requests for this app.
```typescript
@AppConfigDecorator({

@@ -31,3 +94,2 @@ port: 2000,

export class AppMain {
...
}

@@ -40,3 +102,3 @@ export class HeaderExistsValidator implements ValidatorInterface {

validate(params: any, request): boolean {
...
return !!request.headers[this.headerName];
}

@@ -46,12 +108,22 @@ }

The input validators implement ValidatorInterface and return a boolean value.
#### Method specific validators
2. Input transformers - they transform the request data into objects that are passed to the methods
Any number of input transformer can exist per method.
```typescript
@ValidatorDecorator(new HeaderExistsValidator('x-content-type'))
private method1() {
return Promise.resolve(true);
}
```
Similarily to the example above, here we define the validator for this particular method.
### Input transformers
They transform the request data into objects that are passed to the methods. Any number of input transformer can exist per method.
It must return a promise of one parameter.
1. The transformer returns a promise of one parameter type.
2. The order of validators will give the order of parameters in the method call.
3. The transformers implement the TransformerInterface and return a Promise to the type of object they are for.
The order of validators will give the order of parameters in the method call.
The transformers implement the TransformerInterface and return a Promise to the type of object they are for.
```

@@ -91,5 +163,7 @@ export class BucketTransformer implements TransformerInterface {

3. The method itself - this is where the app logic lives
### The method itself
It must also return a promise of a HttpResponse type of object, this object will be returned to the user.
This is where the app logic lives
It must also return a promise of any type of object, this object will be serialized/processed if needed, then replied to the user

@@ -104,4 +178,98 @@ ```

4. TODO: Response serializer - this is where you can decide what exactly ends up in the response.
### Response serializer
This is where you can decide what exactly ends up in the response. Everything in the response can be changed at this step.
In the near future, a functionality to make the server emit events will be implemented.
The serializers must implement **SerializerInterface**.
They must return an object of type JsonRpcResponseType.
```typescript
// example of serializer - removes all keys that contain the string 'test' from the response.
class RemoveTestsSerializer implements SerializerInterface {
serialize(serializeParams: SerializerParameterType): JsonRpcResponseType {
for (const key in serializeParams.objectToBeReturned) {
if (key.indexOf('test') !== -1) {
delete serializeParams.objectToBeReturned[key];
}
}
return serializeParams.objectToBeReturned;
}
}
@SerializerDecorator(new RemoveTestsSerializer())
method4(req, resp) {
console.log('METHOD 4 called');
return Promise.resolve({test2: 'test', ihaveatesttorun: 'Ihaveatesttorun', someKey: 16});
}
```
## Events
### Sending events
One of the core functionalities of the framework is to make sure that methods can asynchronously emit events, on API calls.
The messaging paradigm used is PUB/SUB. This means that the events are published and lost if no subscribers are present.
On the other hand, if multiple subscribers subscribe to the same event, they will all receive the same events.
Easiest way to include the events functionality is through a simple decorator.
```typescript
// step 1 - define the connection & transport
// for now only Rabbit transporters are allowed
@AppConfigDecorator({
messaging: {
serviceName: 'NewService',
host: 'localhost'
},
port: 2000,
services: [NewService]
})
class app {
}
```
```typescript
// step 2 - in the service method, mention the decorator
@ServiceDecorator({
path: '/newpath',
serializer: new RemoveTestsSerializer()
})
export class NewService implements ServiceInterface {
EventEmitterDecorator()
method2() {
return Promise.resolve({sum: 8, product: 15});
}
}
```
By default, this will render a message similar to this
```typescript
{
eventType: 'method2',
eventParams: {
sum: 8,
product: 15
}
}
```
Alternatively, you can also select and change the keys that will be published in the event, by passing a json parameter to the EventEmitterDecorator()
```typescript
@EventEmitterDecorator({
sum: '', // an empty string means the key's name will be used in the event keys
prod: 'product'
})
method3() {
return Promise.resolve({sum: 5+3, prod: 5*3, excluded: 5-3});
}
```
The above example would send a message on the queue which looks like this:
```typescript
{
sum: 8,
product: 15
}
```
Notice how the returned keys are _sum, prod and excluded_, and the event only has _sum and product_.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc