what is good way to share constants between node and angular - node.js

Added at 15 Jan.
What i was worrying is to synchronize protocol values.
below is an API example.
GET /user/:type
type: 'admin' | 'guest' | 'operator'
as much as program get larger, those definitions get larger and more complex and it would be scattered in many places, so adding or changing something take more time.
what I can easily think to solve this problem is use json file.
at the first time each client or server begins, parsing those protocol.json files.
is it only way to solve it?
I hope you to understand what i'm wondering.
how to handle easily large and scattered definition in server and client each side.
I wanna share some enumerate values between client(Angular 6) and server(Node.js).
I have to synchronize some values while communicate client and server.
let me give a example.
// ProductType in Angular
export enum ProductType {
phone,
tablet,
laptop
}
// ProductType in node.js
const ProductType = module.exports.ProductType = {
phone: 0,
tablet: 1,
laptop: 2
}
as you know, it works properly, but I don't think this is good way, because it's getting difficult to manipulate as project is getting bigger and more complex.
what I want to do is share constants between client and server while transferring data.
It doesn't need to be number type, string type is ok.

Related

i can't see difference between put and patch method

I just want to like a quote or dislike if already i liked the quote. So first i find the quote and then i check if i already liked the quote, if not then i like, otherwise i dislike.
I have a router like below
router.put('/:quoteId', isAuth, quotesController.likeQuote);
And likeQuote method is like below
module.exports.likeQuote = (req, res, next) => {
const quoteId = req.params.quoteId;
const userId = req.userId;
Quote.findById(quoteId)
.then((quote) => {
if (quote.likes.indexOf(userId) == -1) {
quote.likes.push(userId);
} else {
quote.likes.pull(userId);
}
return quote.save();
})
.then((updatedQuote) => {
res.status(201).json({ message: 'You liked the post!' });
})
.catch((err) => {
err.statusCode = 500;
next(err);
});
But my question is, i just want to know how PUT and PATCH works? I think we should send all the fields in PUT but not in PATCH methods, but in my case i don't even send any fields and both work just fine.How this happens?
The actual REST API methods (PUT, PATCH, ... ) do not have any limitations. the logic you choose to write is what defines this. Now you're asking about "best practices" and whenever you ask about that you will get many different answers. I'll explain my view.
PUT, so the essence of PUT is to replace the existing object completely, that's why people are telling you to send the entire object because when you use PUT what's expected is a complete swap.
PATCH, the essence of PATCH is to update the existing resource. which is in your case what you're looking for, in this case you just send the required fields you need for the update.
Now is it wrong if you write PUT to be an update and not a complete swap? I would argue it is not. As long as you keep consistent logic throughout your app you can build your own "best practices" that will suit your needs.
Now you did tag this question as Mongo related so I would like to introduce to you the concept of piplined updates (for Mongo v4.2+) where you can execute your logic in 1 single update.
Mongo Playground
i just want to know how PUT and PATCH works?
An important distinction to understand is that we don't have a standard for how PUT and PATCH work; that's a implementation detail, and is deliberately hidden behind the "uniform interface".
What we do have is standardized semantics, an agreement about what PUT and PATCH mean.
(This is further complicated by people not being familiar with the standard, and therefore misinterpretations of the meaning are common.)
If the implementation of the request handler doesn't match the semantics of the request, that's OK... but if something goes expensively wrong as a result, it's the fault of the implementation.
PUT and PATCH are both method-tokens that indicate that we are trying to modify the resource identified by the target-uri. In particular, we use those method-tokens when we are trying to make the server's representation of the resource match the representation on the client.
For example, imagine editing a web page. We GET /home.html, change the TITLE element in our copy, and we want to save our changes to the server. How do we do that in HTTP?
One answer is that we send a copy of home.html (with our changes) back to the server, so that the server can save it. That's PUT.
Another answer is that we diff our copy and the server's copy, and send to the server a patch-document that describes the changes that the server should make to it's copy. That's PATCH.
router.put('/:quoteId', isAuth, quotesController.likeQuote);
What this invocation is doing is configuring the framework, so that requests with the PUT method token and a target-uri that matches "/:quoteId" are delegated to the likeQuote method.
And at this level, the framework assumes that you know what you are doing - there's no attempt to verify that "likeQuote" implements PUT semantics. To ensure that the implementation and the request semantics match, you are going to need to do some work (inspect the code, test, etc).
in my case i don't even send any fields and both work just fine.
Right - because the framework assumes that you know what you are doing, and your current implementation doesn't try to access or interpret the body of the HTTP request.
Note: that's a big hint that the request handler not actually implementing PUT/PATCH semantics (how could the server possibly make its copy of the quote look like the client's if it doesn't look at the information the client provided)?
It is okay to use POST; assuming that your implementation is correct, you should not be using methods with remote authoring semantics, because that's not what you are doing. This same implementation attached to a POST route would be fine.
As is, things are broken - you have a mismatch between the request semantics and the handler implementation. Under controlled conditions, you are likely to get away with it. It's entirely possible that you are only going to be invoking this code under controlled conditions.

How do I manage groups/rooms with node WebSockets?

TL;DR below.
I am currently developing a React/Redux SPA that is driven by real-time data. I've decided to use ws, instead of socket.io since socket.io feels a bit high level for what I'm doing, I'd rather manage sockets myself.
In saying that, I'm struggling to find a way to manage the separation of updates/messages per view/route. Since I'm using client-side routing it's per express route won't really work...
Messages between the server and client via WebSockets are JSON with actions like GET_ITEMS then a response of GET_ITEMS_SUCCESS with an array of 'items' and for errors: ..._ERROR etc. This is all fine, since it's just 1 to 1 transaction. Though the problem arises when broadcasting (1 to all) to all relevant clients when the server receives an update.
So, I assume it best practice to limit these broadcasts to the clients that are viewing/want the data. So when viewing, for example, the Item page, there is no point in broadcasting updates to the User data since that is only used on the User page.
I haven't been able to find any common practices when dealing with this sort of situation, just a few small outdated/barely used wrappers for ws that just add a few basic functions to leave/join but don't offer much flexibility with implementation.
What I think MIGHT work is to have an object/array for each 'group'/'room', which stores the clients that are currently listening to updates from a given section. So a user would send an action to INIT_LISTEN (& ``) with a param of category, e.g. ITEM for updates and other actions related to items.
TL;DR
What my question really boils down to is: How do I store a reference to a single socket? (ws client object? ws client ID?) Then, can I store this in an object/array to iterate through like below.
const ClientRooms = {
Items: {
{
...ws
}
/* ...rest of the client */
}
}
or
const ClientRooms = {
Items: [ "xyz" ] /* Array of ws ids */
}
I have a "ping--pong" heartbeat function to keep clients active and prevent silent connection failures/disconnections. I can't find if ws.terminate() still fires the ws close event so I can iterate 'group'/'room' the object/array to find and remove instances of that client.

socket.io - io.sockets.adapter object?

I'm experimenting with socket.io and trying to build a multi-room chat app. The guide I'm following is out of date using pre 1.0.0 socket.io.
I'm trying to find a list of connected clients in a given room. Googling around shows that I have to use the adapter. However, I cannot find the documentation for it anywhere. I searched for it in the git-hub doc but search didn't return any information on adapter. https://github.com/socketio/socket.io-client/blob/master/docs/API.md
Can someone point me in the right direction and where I can read more about adapter and associated methods on it? Also if you can provide the most up to date documentation for socket.io I'd greatly appreciate it. Thank you.
You can get a map of all rooms in the top level namespace like this:
io.nsps['/'].adapter.rooms
You can list the sockets in one of those rooms like this:
function getSocketsInRoom(room, namespace = '/') {
let room = io.nsps[namespace].adapter.rooms[room];
return room.sockets;
}
As best I can tell, this kind of stuff is simply not documented. I've only discovered things like this by examining how things are stored in the debugger. That may or may not mean it's subject to change in the future - I really have no idea.
sockets:
{ '2v8OmIS4qTGX61-YAAAC': true, '3YnScxOgpmAGhZWsAAAG': true },
length: 2 }
it gives u this output. So it basically gives you the clientId and whether it is connected or not and total number of clients connected to a specific room. When the code below is executed (in server side written in node.js) gives u the above output.There is currently two clients connected to the same room named "hello".
var clientsInRoom = io.sockets.adapter.rooms[room];
but when u write this code below and console log it
var clientsInRoom = io.sockets.adapter.rooms
when single client is connected it will console log this
{ '9mVAHSDwcwnqsF4aAAAA':
Room { sockets: { '9mVAHSDwcwnqsF4aAAAA': true }, length: 1 } }
this crazy '9mVAHSDwcwnqsF4aAAAA' literals is client id which is unique for each client

Breaking up node module code (for a library/api client)

I'm writing a node module to consume a REST API for a service. For all intents and purposes we might as well say it's twitter (though it's not).
The API is not small. Over a dozen endpoints. Given that I want to offer convenience methods for each of the endpoints I need to split up the code over multiple files. One file would be far too large.
Right now I am testing the pattern I will outline below, but would appreciate any advice as to other means by which I might break up this code. My goal essentially is to extend the prototype of a single object, but do so using multiple files.
Here's the "model" I'm using so far, but don't think is really a good idea:
TwitterClient.js
function TwitterClient(){
this.foo = "bar";
}
require("fs").readdirSync("./endpoints").forEach(function(file) {
require("./endpoints/" + file)(TwitterClient);
});
var exports = module.exports = TwitterClient;
endpoints/endpointA.js etc
module.exports = function(TwitterClient){
TwitterClient.prototype.someMethod = function(){
//do things here
}
}
The basic idea obviously is that any file in the endpoints folder is automatically loaded and the TwitterClient is passed in to it, so that it's prototype can be accessed/extended.
I don't plan to stick with this pattern because for some reason it seems like a bad idea to me.
Any suggestions of better patterns are very much appreciated, cheers

Resolve MongoDB reference

I am currently building a chatting app with nodejs and mongoDB.
Basically I have two collections to maintain in the db.
user = {
_id: ObjectId("1234"),
account: "stan123"
}
thread = {
_user: ObjectId("1234"),
messages: [
{
body:"hi"
_user:ObjectId("1234")
},
{
body:"second msg"
_user:ObjectId("1234")
}
]
}
I am planning to pass the thread model with all resolved info (user) to the client side, so that I can construct my widget with it.
I searched for solutions for this.Some suggests to make extra calls from client side to get the data.
However, I am worried that when the amount of message grows, there will be considerable http calls that might hurt site speed.
I know some drivers can resolve DBRefs automatically and make the code clean.
However, according to
http://docs.mongodb.org/manual/applications/database-references/
I decided to just use id to maintain reference that make it's as simple as possible.
My plan is resolving all references on server side. Current approach is getting the length of message array first.
Then loop through the message array and make a second query to resolve user info separately.
In each query callback, do a messageToResolve++ and if(messageToResolve >= thread.messages.length)
If the condition meets, send the resolved model to client and end the response.
This is not a case I would consider embedded because it would be painful when you need to update user data.
(message is embedded because it exists only when thread exists)
I am not sure if it's a good way to do it.
Does anyone has a better solution?
Sorry if I didn't explain my problem and solution clear enough.
And thanks in advance.

Resources