 Today I'm going to talk about a small implementation which was done in JavaScript and it came for actually came for a code review and then we just applied very basic principles. I would not even say it's a p-principle, it's applicable even for others but yeah a few of the very basic stuff and then how did the application design evolve and it's kind of started and how it kind of made it more modular and how we could you know just add features on top of it like incrementing features on top of it. This was a 45 minutes talk which I planned early so now I'm just condensed it to 20 minutes so just go a little bit faster. So I'll skip this okay so this is again like so I'll not be going into details about the design and architecture or design stuff and what really happened so just go through the entire flow of what really the changes that we went through. So this is the app so it's a kind of a messaging adapter so we have this I won't use the real name so it's like some kind of a free messenger so it's in the cloud and there is an enterprise messaging so you want to bridge these two like there are some users from outside it's to be able to reach your enterprise users so this so the adapter that's that's a component which we built which enables us to know bridge these two messaging and the signaling part of it so that's that the subject of this discussion and of course I talked about this is this is running on node this adapter and this is what it looked like when we finally said we are done we are done in the same scheme for the review like completed the intimidation that means it's a all all it's like one more one node module which embeds a glue to connect to that FM or the messenger service in the cloud and it does everything like it reads its config it uses it it bridges the messages it bridges signal it does everything it talks to the enterprise it's all in one so we talked to it got the messages from the FM and send it to it enterprise and reverse direction right six signaling and messages so it's a single module which does did everything so I'll okay I'll skip this part now challenges around display so I will go through at the end like comparing the what was there initially and what what end product so what did we do that it's a very first step so it's it's pretty I think it's straightforward like it's doing a lot too many things right so it's not just doing one thing it's doing too many things and so you decouple what the interactions that has to do with that free messenger service versus the interaction that has to do with the enterprise messaging service so it's at a higher level function to see why higher level capabilities you make that more modular so again there is really space really know that thing here's a general practice so what it created is these two probably quite a sub modules or something like that but in which all the FM part in one end and all the EMPM part in another end and the distinction here it is it's community they are they are exchanging messages they don't like FM really does not know what is happening so it just sends the message to you it does taking care of you know talking relevant API so on to enterprise messaging service so there's no doubt it's totally decoupled and it is the interface between them is data that is the message that is that's being sent it's actually a recipe client so next step so this was the first of it we did that and the next what we did is if you see the previous image this has like a config FM glue so that's those are like mutable state which is at the global level like the config changes my global state changes if I need to support another set of credentials or another messaging service my FM blue changes no it's it's it's so it's it's at global level and it could change so what we did is we took that out and of course when you take that out you add it as a parameter in various function that needs it so parameterize the functions and another point which we did is wherever possible to a limited extent we made some of the functions beyond like all the side effect impact took it out not to the full-scale but certain part of it so that gave us this where in which yeah you have some entity which is kind of treating the config it's creating the blue and then passing it on to your actual module so it's it's these are like injected parameters so I've shown you're only like the major ones the actual changes are largely because it's a lot of function for using these and other parameters so here again it's essentially the most important thing is parameterizing the functions that's all it is and remove the global state so that was a step two and step three this is again very specific but I thought it's a nice idea I wanted to bring it out here it's like use function instead of a value if you see that config config was a value earlier and we had challenges around in multiple places like if that config changes how do you know kind of handle those changes propagating the changes to multiple places so what we really passed on is actually not a config it's a function like you invoke it and you get a conflict so that kind of took care of like you know at any point of time if conflict changes like every time somebody wants to wants a conflict you invoke the functions you get the latest and the last one we look at the actual part of the system that does stuff right for example these fm of the messenger service invokes their hooks that means so you have some APN point defined so that's those and there's a lot of I.O. and similarly to the enterprise messaging you have to invoke APA this is essentially the rest APA client that's again I.O. these are the part of the system which does did real job how do you make those parts pure so we didn't want to do that but then again we were facing issues or rather we are test were not looking that good I mean like a lot of mocking and we are to to you know kind of validate various scenarios where the payload changes the response changes you know to do it by a mocking was a bit challenging or it was not straightforward somebody who is coming and reading it out it's not straightforward so you thought okay why don't we make that pure so all side effects wherever like you are like making an API call essentially in this case there is no DB or a file or config reading is a file actually but moved to a smaller part of your application so that gave us this were in which you have those pink circles that's that's the part of the system which actually does all the job so these are like calling it as effect turner so that that that does the job restaurant or pure functions so if you had a we had a we had a function like you know send message to user that was actually invoking any pay with a specific payload and all those kind of things now it no longer does that what it does is it returns you a structure JSON or a message data which say which is given to the effect turner and say that oh the effect turner will know that for this data I need to send a I need to know the corresponding API so to test that message the test case is like okay you don't need any mocking for various in type of inputs here is the message that I expect in this content again some of these were done like you know to really trying out like if I want to move all this thing away into one place and then how does our application change how do I handle what is my response channel so with this what we got was so in the original implementation we had this there was one module all the methods were doing some kind of you know the effects were actually all over the place it's like typical stuff where we have something okay send message send receive message add user in case let's say group channel like you were adding another user and all this kind of things and you had a there was a tight coupling between your external messaging service in this case and the enterprise interaction because all are done from one single place there is no decoupling and it was kind of difficult to support newer one let's say if you want to let's say add WhatsApp or Facebook or any kind of messaging it's it's kind of difficult you need to kind of tear apart things to get that out or more yeah more than that it's about what if you're an enterprise messaging changes that's again bunch of effort to tear things apart so that's a last point it was kind of restricting only for one FM EM pair that's for that you scared it was beautiful it was beautiful and that was only use case we need to support but anyway so that's that's what it is but after the refactoring of course we don't have a no globally mutable shade state as I told before like all the effects are done only in those two effect runners which is a which is like probably 20-30% of the code and all these effects like I need to do something goes as a data like this and structure like what needs to be done and it enabled testing the rest of the part like except the effect runners first all the modules we could test it very easily and it's kind of supported it was very I'm really not to make many code changes okay I need to support additional service or I need to support more than one you know instances of this like for example your integration with your third-party messaging is through using one one set of credentials one account so I need to support like multiple accounts like that it's essentially you call the same function again with the difference of parameters that's what it is okay so now let's look at the original implementation and what happened after the factoring alright so I'll I'll take I'll show like okay not that great but still I think it's readable is it is it readable from the back font size okay okay alright so if you see the this is the original implementations we had one thing called add from route to the express module in the node which gave us the API's and what it does is it reads a config and it says it okay it's at for a particular uri it adds the route but let's rest of the intelligence is showed in this implementation of this so that's that's all here so this is again the original one of that so here if you see so it's exporting these of course the uri the initialization part of it so this so if you this points to a thing like okay it's checking whether this is set and it's not set in each line so this is the global state right so we'll check it so that's what it is so this this is global and it's kind of used in across all the methods and all the all the functions over here are like directly in working the corresponding API because this guy will do the actual API invocations so send action and text so all those things are directly used in the API so that means all of the functions that you defined here are actually making API calls outside either to the outside world or to the enterprise what offers now yeah this is what it is so two files the one which did everything another one which actually you know registered the route now as per the first step what I told you we separate out the enterprise part with the external part right so that created a new new module so this is like enterprise message gateway stuff so this is again press API client around it and the important thing is now how did the application evolve right so now here if you see so there is so now this is an example where we are at two different channels like one two different integration this is one this is the second one it's just a test service which is running so here if you see so what it what it did is okay it's initializing the channel it's telling what type of channel it is and it is providing a configuration it's another function which when invoke will give you the config of config for it similarly for another one it's again the same function you're calling out this is of type different and this is a corresponding so if you go to each channel so this again yeah so it takes the type and it gets the corresponding config so essentially the your initial module which loads with which which takes the different objects the different data and then passes it on to the relevant functions essentially it's only the parameterizing the function that's that's done over here and here yeah so here if you see the exported functions over here yeah so it's an uri it's an init and it's with router it all of these things it's passing all the parameters over here and the interesting thing is okay we have something called do so in this module and this do is the effect runner actually so do accepts whatever it needs to run and any messages that it receives it translates to the corresponding stuff if you see the defect turner so this is what it is so it's all the things are over here like sending the problem sending the text sending the buttons sending text message all of things are effect runner and how that is triggered is this one right it's like you get a message for this message ID this is what we need another message is what we need so that's it's actually the same concept even here where you have a dispatcher in case starting the chat so all the business logic stuff like if I need to start chat it will create a message called start chat and send it over to the defect turner so it does the job any questions so what that gave is kind of something like this where in which you have an outer layer which does all the effects in this case actually there's no db over in this case it's just invoking API that's what it is doing but you have two systems in working API source and target of two different systems and there is an inner core which is done fully using pure functions and these layers talk to each other over messages that's it yeah so there are there's a comp in certain cases these functions return the corresponding message I'll show you that let's say so now I'll go to this sorry factor stop right so now here so this is an example let's say start chat earlier this was actually invoking doing a bunch of stuff and invoking API so this guy is now actually returning this message it was start chat with the data that is needed so this is a very simple case like and I just need only two strings so it is returning that particular message now let's look at whoever invokes this so that will give us so here this is invoking okay so let's look at this okay so in this case this handle post backing session this was earlier doing all the work so now it is returning it this guy is getting getting an effect and it's doing dispatch effect so dispatch effect yeah it's it will find the corresponding executable for that particular effort and send it to that so this this this in certain thing where it is not it's only