2

I have a backend api with express. I've implemented logging with winston and morgan.

My next requirement is to record a user's activity: timestamp, the user, and the content he've fetched or changed, into the database MySQL. I've searched web and found this. But since there is no answer yet, I've come to this.

My Thought: I can add another query which INSERT all the information mentioned above, right before I response to the client, in my route handlers. But I'm curious if there could be another way to beautifully achieve it.

Htet Phyo Naing
  • 464
  • 7
  • 20

1 Answers1

1

Select the best approach that suits your system from following cases.

Decide whether your activity log should be persistent or in memory, based on use case. Lets assume persistent and the Db is mySQL.

If your data is already is DB, there is no point of storing all the data again, you can just store keys/ids that are primary for identification, for the rows which you have performed CRUD. you can store as foreign keys in case if the operations performed are always fixed or serialised JSON in activity table. For instance, the structure can be shown as below, where activity_data is serialised JSON value.

ID | activity_name | activity_data | start_date | end_date | 

If there is a huge struggle while gathering the data again, at the end of storing activity before sending response, you can consider applying activity functions to the database abstraction layer or wrapper module created for mySQL (assuming). For instance :

try {
    await query(`SELECT * FROM products`);
    //performActivity(insertion)
}catch{
    //performErrorActivity(insertion)
}

Here, we need to consider a minor trade off regarding performance, as we are performing insertion operation at each step.

If we want to do it all at once, we need to maintain a collection that add up references of all activity in something like request.activityPayload or may be a cache and perform the insertion at last.

If you are thinking of specifically adding a new data-source for activity, A non-relational DB can be highly recommended to store/dump such data (MongoDB opinionated). This is because it doesn't focuses on schema structure as compare to relational DB as well you can achieve performance benefits as compare to mySQL specifically in case of activity storing.

bron10
  • 151
  • 2
  • 11
  • Thanks for your answer. Yes. I'm using Node with MySQL. Can't use NoSQL for whatever reasons. Can I write those codes inside `middleware`? – Htet Phyo Naing Aug 27 '20 at 10:20
  • 1
    Yes you can, making sure you collect all the data in any key in `request.activityPayload` and append a middleware at the end, that will insert this data and send response. well I also think, the insertion operation if is not so dependent you can keep it asynchronous while letting your response go ahead if that suits. – bron10 Aug 27 '20 at 10:29
  • @bron10 how about using events? Like you can emit an event and pass payload object with all the data to the event and have a central event listener which can save all the activities in the database. – Rafay Hassan Dec 03 '20 at 17:39
  • Sure the mode of passing data can be some singleton methods of wrapper function or can be event as you suggested. Unless author, don't prefer to do it asynchronous and is willing to maintain callbacks, which I usually don't prefer nowadays, unless dealing with something that is core node module. Seems like i am opinionated about it :), but to answer in short, yes that's a nice approach. It will help author to maintain saving activity as a separate service. – bron10 Dec 07 '20 at 11:15