just-another-http-api 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api.js +32 -16
- package/config/default.js +7 -0
- package/package.json +3 -2
- package/utils/WebsocketGroup.js +60 -0
- package/utils/websocketHandler.js +14 -0
package/api.js
CHANGED
|
@@ -32,6 +32,9 @@ async function createServer ( config ) {
|
|
|
32
32
|
if ( config.cors ) {
|
|
33
33
|
app.register ( require ( '@fastify/cors' ), config.cors );
|
|
34
34
|
}
|
|
35
|
+
if ( config.websocket?.enabled ){
|
|
36
|
+
app.register ( require ( '@fastify/websocket' ), config.websocket?.options );
|
|
37
|
+
}
|
|
35
38
|
await uploads.initialiseUploads ( app, config );
|
|
36
39
|
await caching.initialiseCaching ( app, config );
|
|
37
40
|
await auth.initialiseAuth ( app, config );
|
|
@@ -83,12 +86,13 @@ function registerEndpoint ( app, endpoint, globalConfig ) {
|
|
|
83
86
|
|
|
84
87
|
const fastifyMethod = translateLegacyMethods ( method.toLowerCase () );
|
|
85
88
|
const handler = endpoint.handlers[ method ];
|
|
86
|
-
const wrappedHandler = fastifyHandlerWrapper ( handler, endpoint.handlers.config, globalConfig );
|
|
89
|
+
const wrappedHandler = fastifyHandlerWrapper ( handler, endpoint.handlers.config, globalConfig, method );
|
|
87
90
|
|
|
88
91
|
app[ fastifyMethod ] (
|
|
89
92
|
endpoint.path,
|
|
90
93
|
{
|
|
91
|
-
preHandler: preHandlers
|
|
94
|
+
preHandler: preHandlers,
|
|
95
|
+
websocket: handlerConfig?.websocket || false,
|
|
92
96
|
},
|
|
93
97
|
wrappedHandler
|
|
94
98
|
);
|
|
@@ -104,22 +108,34 @@ function translateLegacyMethods ( method ) {
|
|
|
104
108
|
}
|
|
105
109
|
}
|
|
106
110
|
|
|
107
|
-
function fastifyHandlerWrapper ( handler, config, globalConfig ) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
+
function fastifyHandlerWrapper ( handler, config, globalConfig, method ) {
|
|
112
|
+
if ( config?.[ method ]?.websocket ){
|
|
113
|
+
return handler;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
return async ( req, reply ) => {
|
|
117
|
+
try {
|
|
118
|
+
let response;
|
|
119
|
+
if ( globalConfig?.cache?.enabled ){
|
|
120
|
+
const request = { method: req.method, query: JSON.parse ( JSON.stringify ( req.query ) ), routeOptions: req.routeOptions };
|
|
121
|
+
response = await caching.checkRequestCache ( app, request, reply, config, globalConfig );
|
|
111
122
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
if ( !response ){
|
|
124
|
+
response = await handler ( req );
|
|
125
|
+
await caching.setRequestCache ( app, request, response, config, globalConfig );
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
response = await handler ( req );
|
|
130
|
+
}
|
|
116
131
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
132
|
+
handleResponse ( reply, response, req.method, req.routeOptions.url );
|
|
133
|
+
}
|
|
134
|
+
catch ( error ) {
|
|
135
|
+
handleError ( reply, error );
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
123
139
|
};
|
|
124
140
|
|
|
125
141
|
function handleResponse ( reply, response, method, path ) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "just-another-http-api",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"description": "A framework built on top of fastify aimed at removing the need for any network or server configuration. ",
|
|
5
5
|
"homepage": "https://github.com/OllieEdge/just-another-http-api#readme",
|
|
6
6
|
"repository": {
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"@fastify/cors": "^8.4.1",
|
|
31
31
|
"@fastify/jwt": "^7.2.3",
|
|
32
32
|
"@fastify/redis": "^6.1.1",
|
|
33
|
+
"@fastify/websocket": "^8.2.0",
|
|
33
34
|
"abstract-cache": "^1.0.1",
|
|
34
35
|
"abstract-cache-redis": "^2.0.0",
|
|
35
36
|
"fastify": "^4.24.3",
|
|
@@ -42,4 +43,4 @@
|
|
|
42
43
|
"eip-cloud-services": "^1.1.0",
|
|
43
44
|
"mocha": "^10.2.0"
|
|
44
45
|
}
|
|
45
|
-
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const crypto = require ( 'crypto' );
|
|
2
|
+
const { redis } = require ( 'eip-cloud-services' );
|
|
3
|
+
|
|
4
|
+
class WebsocketGroup {
|
|
5
|
+
|
|
6
|
+
constructor ( groupName ) {
|
|
7
|
+
this.groupName = groupName;
|
|
8
|
+
this.connections = new Map ();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async initialize () {
|
|
12
|
+
try {
|
|
13
|
+
await redis.subscribe ( `${this.groupName}_broadcast`, this.handleMessage.bind ( this ) );
|
|
14
|
+
await redis.subscribe ( `${this.groupName}_messageReceived`, this.handleUserMessage.bind ( this ) );
|
|
15
|
+
}
|
|
16
|
+
catch ( error ){
|
|
17
|
+
console.log ( error );
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
handleMessage ( message ) {
|
|
22
|
+
this.broadcastMessageToClients ( message );
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async handleUserMessage ( userMessage ) {
|
|
26
|
+
// don't really need to do anything with this message.
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
broadcastMessageToClients ( message ) {
|
|
30
|
+
this.connections.forEach ( conn => {
|
|
31
|
+
conn.socket.send ( JSON.stringify ( message ) );
|
|
32
|
+
} );
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
addNewConnection ( connection, connectionId = crypto.randomUUID () ) {
|
|
36
|
+
this.connections.set ( connectionId, connection );
|
|
37
|
+
|
|
38
|
+
connection.socket.on ( 'message', async message => {
|
|
39
|
+
const userMessage = {
|
|
40
|
+
groupName: this.groupName,
|
|
41
|
+
connectionId,
|
|
42
|
+
message: message.toString ()
|
|
43
|
+
};
|
|
44
|
+
await redis.publish ( `${this.groupName}_messageReceived`, JSON.stringify ( userMessage ) );
|
|
45
|
+
} );
|
|
46
|
+
|
|
47
|
+
connection.socket.on ( 'close', () => {
|
|
48
|
+
this.connections.delete ( connectionId );
|
|
49
|
+
} );
|
|
50
|
+
|
|
51
|
+
connection.socket.on ( 'error', error => {
|
|
52
|
+
console.error ( 'WebSocket error:', error );
|
|
53
|
+
this.connections.delete ( connectionId );
|
|
54
|
+
} );
|
|
55
|
+
|
|
56
|
+
return { connectionId, groupName: this.groupName, connection };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = WebsocketGroup;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const WebsocketGroup = require ( './WebsocketGroup' );
|
|
2
|
+
|
|
3
|
+
const websocketGroups = {};
|
|
4
|
+
|
|
5
|
+
const getGroupInstance = async ( groupName ) => {
|
|
6
|
+
if ( !websocketGroups[ groupName ] ) {
|
|
7
|
+
websocketGroups[ groupName ] = new WebsocketGroup ( groupName );
|
|
8
|
+
await websocketGroups[ groupName ].initialize ();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return websocketGroups[ groupName ];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
module.exports = getGroupInstance;
|