This is going to be a optional video.
Hundred percent optional.
So if you just want stay focused on the topic at hand.
Plus a video right now and continue on.
Otherwise stick around and I'll tell you what we're going to discuss in this video.
So I want you to notice how between our ticket service and the order service we use that exact same
module to manage all that versioning stuff.
So we made use in both services of that module called Mongoose update if current.
Now to be honest with you that was kind of cheating.
We are kind of cheating by using this module inside of both these different services.
Let me tell you why.
By using this service or that module we are able to assume that this order is database right here in
all the tickets inside of it are essentially going to manage themselves.
So in other words whenever we have some incoming event come in we're going to go through that process
of subtracting the version number to find the appropriate record.
We then apply some updates that record and then specifically a real gotcha here is that this module
when we save the updated ticket it is going to take the version number right here already inside of
our database and incremented by 1.
So that module alone is responsible for updating the version number inside of our orders database right
now.
Is that a bad thing.
Well I would argue yes it is.
And here's why right now we are 100 percent aware of where these events are coming from.
We know they're coming from the ticket service and we know exactly how the version numbers work inside
that ticket service.
We know that they start off at zero and they are incremented by 1 every single time.
So we are able to make use of the Mongoose update if current module inside the order service just because
it matches the exact same versioning semantics as the ticket service.
But there might be some kind of scenario out there at some future point in time where these ticket updated
events are coming from a totally different kind of database.
Maybe it's not a mongo database maybe it's something that doesn't use Mongoose might be a totally different
kind of information stored and with these other kinds of information stores we cannot necessarily always
rely on them using the exact same versioning semantics as this Mongo Mongoose update if current module
so inside of some alternate universe we might have these events coming in from some other part of our
application.
We don't really know and they still might look identical so there's still ticket created.
Ticket updated tick up tick it updated but they might have an entirely different schema for applying
versioning numbers so they might start off with a version number of one hundred and then increment by
one hundred for every successive version.
And if that was the case we could definitely not make use of this very easy to use module inside of
our order service because it is always assuming though our versioning starts off at 0 and increments
by 1 every single time it update is issued besides having this very different kind of versioning where
we start off at 100 in and increment by 100 every single time there might be some other database that's
emitting these events or some other service that's limiting these events and they might use a version
that has a timestamp to indicate when this record was St. And so once again maybe that time stamp doesn't
work too well with the Mongoose plugin we are using among these plugin we are using does technically
support timestamps Well it's imagined for whatever reason these timestamps are not interoperable for
some reason.
Who knows.
I don't know.
The point here is that we are kind of cheating by allowing all these version numbers inside the orders
database to just be managed by that plugin.
So the goal of this video what I want to do I want to try to remove that plugin from the orders service
and I want to show you how we could implement all the same versioning kind of stuff and manage the version
numbers increment the version numbers on our own rather than relying upon the module that we installed.
That's the goal of this video.
So if that doesn't sound interesting.
No problem.
Just pause video skip on ahead.
Just you know we are going to revert all the changes we're going to make in this video.
So this is solely for informational purposes just to understand that we are not really tightly coupled
to this burgeoning module that we just installed.
So don't mind the first thing we have to do to somehow replace this plugin is understand what it actually
does.
So there's really two primary goals of that plug in right now.
Here's what it really does so it's going to update the version number by one on records before they
get saved.
That's step number one as the first thing it does.
The second thing that it really does is it customize as the find and update operation.
So remember that's when we actually save a record when we save a record.
Mongoose is going to make that request ever to mongo and it's going to say not only try to find some
record with this idea and update it this module is also going to modify that query and change it into
find a record with this I.D. And this particular version number and update it does the two things that
this module is really doing for us.
So these are the two behaviors that we need to somehow replace.
So to speak we're going to first focus on step number one.
How are we going to somehow make sure that this version number can somehow get updated or whatever it
is without having to rely on this module.
Well for that I'm gonna go backwards.
My listener so inside the listener at some point time we take some information out of this incoming
event set it on our ticket and then save it.
There is technically another piece of information on this data object the version property to the version
that is contained inside that event is what we want to update our local ticket to have.
Remember that was super key and all these flow diagrams so we went through back over here every single
time we had said that we were going to say process this event we were going to find the appropriate
record inside the database by taking that version right there subtracting one and finding the appropriate
record we would find this record right here.
We would then update the price and then update the version on this thing to really not just incremented
by 1 but really what we're doing here is incrementing it to be equal to the version inside of this event.
And so right now we are able to rely upon that plugin because it's going to increment by one for us
automatically which is really what we want.
But again what if this was a totally discontinuous version no.
What if it was incremented by 100 or something like that.
Well then we would have to somehow jump in and extract that version number and assign it to our record
inside the database so we would take three not just because we are taking two plus one but we would
assign version three specifically because that is what is inside this event right here so how we can
reflect that inside of our code when we pull off some data from some information from that data object
and then set it on our document and save it.
We could also just pull off the version assign it to our document and that's it.
So this now achieves the exact same thing that that plugin was doing for us.
But now we are no longer coupled to this plugins understanding of how these virgin numbers increment.
Instead we are using the precise version that was included inside of this data object.
So now inside that data object we could potentially have version numbers like this right here where
they are incremented by one hundred every single time or we could potentially have timestamps.
It really doesn't matter we're just saying take whatever this new version number is inside this event
assign it to our record and save it because now that is the current version that kind of solves step
number one right here.
As easy as that was we're just copying over that one property and that kind of handles this idea of
updating that version number.
Now step number two we need to make sure that when we reach into our database to save this record we
need to somehow customize the query that is used.
So this is where life gets just a little bit more challenging.
I want to first show you some documentation over on Mongoose on how we can essentially inject something
to customize this update operation.
Now just you know the Mongoose documentation is not the best in the world.
In addition the typescript type definition file that we are using is also not really gonna show us some
information about this feature.
I'm going to show you as well though this is where we're going to get a little bit hacky so to speak
just so you know.
So if you take a look at the Mongoose documentation we can see that on the model class there is technically
a dollar sign where property and we can modify this dollar sign where property and this will attach
some additional properties to the query that is executed when calling save and win is new is false.
So in other words long story short this does exactly what that module does or what this update if current
plugin does this can allow us to kind of inject some additional criteria on the query that is issued
when we tried to update a record.
So this is where we can add in some additional step and say hey we don't only want to find the record
with the correct I.D. We also want to find some correct record with the correct version and then update
that record.
So this property right here is essentially how we would kind of override or add in some additional query
properties.
Now the reason I mentioned that the documentation is not great here that the type definition file is
not great is that understanding how to actually set this thing is a little bit challenging.
So again this is where life is going to get just a little bit hacky.
But let's just write out the code and see where it goes.
So back inside of my ticket model definition file.
So this again is inside the order service.
So inside order service models ticket T.S. I'm going to scroll down
to right after we set our ticket schema and the plugin while I'm here.
I'm going to comment out the plugins that we're not using this thing at all anymore.
So now we're kind of on our own right.
We have to make sure that whenever we tried to write some records to the database we are writing to
the correct record or the record with the right ideas and the right version so right after that we're
gonna set up a pre save book
re not preview.
So this is a middleware that's going to run any time that we try to save a record.
We're gonna make sure that we provide a function with the function keyword because like many other Middleware
is in Mongoose the value of the document that we're trying to save is available inside this function
as this.
And if we used an arrow function here that would override the value of this inside the function and
all the sudden things would not work as expected.
We must make use of the function keyword also remember that this function is going to receive a single
argument of done.
This is a callback function that we have to manually invoke.
Once we've done everything we intend to do inside of this this middleware.
Oh my apologies there.
Back over here so inside of your reach are going to dynamically you're kind of on the fly a reassign
that dollar sign we're property we're going to put in some additional criteria on the Save operation
in how mongoose is going to find the record to actually overwrite or update inside of Mongo DB.
We're gonna say this dot dollar sign where is going to be an object we're gonna set version equal to
whatever the current version is minus one.
So we'll say this dot get version minus one and then right after that I'm going to call done and you're
going to notice that we get an error right here on dollar sign where if I mouse over it's going to say
that a document does not have a dollar sign where property.
This is where the typescript type definition file for Mongoose falls a little bit short.
It doesn't understand that this property exists.
So this is something is kind of erroneous on typescript side.
Let's just doesn't quite understand what's going on here.
So this is another scenario we're going to tell typescript hey just don't sweat it we know what we're
doing here.
We're gonna put it in a T.S. ignore like so just to get that air to go away.
So what is this going to do.
Well it's gonna do the exact same thing that we saw in many of these different diagrams when we reach
out to mongo DB to save this record.
We're not only going say it try to find a record with some appropriate I.D. but also a version equal
to the current version minus one.
Now the minus one right here once again makes a really big assumption.
It assumes that we are incrementing all these version numbers by one every single time.
So if you were in a scenario where the version numbers were say being invented by one hundred.
This is where to find the previous version the one that we are trying to reach into our database and
update.
This is where we would change this minus 1 to minus 100 or whatever else.
So this function right here is pretty much where we get the ability to kind of modify how the version
is being changed over time but in this case we actually are incrementing the version number by one.
So we would put in simply at minus one right here and believe it or not that is it.
We now do not need that plugin anymore now to test this out.
I'm going to say this file and I'm going to save the listener and then we're going to attempt to create
a new ticket and then we'll update it once or twice and we're going to see it that well everything still
works as expected so I'm going to go backward a postman
every go in postman I'm going to create yet another ticket so I got my post up here to API such tickets
to ticket created I'll then take the idea that ticket was just created go to my put tab so making it
put request to API tickets and I'll paste in my I.D. for the ticket I just made and then I'll update
the price on this one to five hundred I'm going send that off I'm going to go over to my terminal scaffold
once again and just make sure that I don't get any errors so it looks like everything's still worked
as expected that version query is still working even though we're not using that plugin and if I wanted
to I can make yet another price change right here let's say go to 2000 send that off.
Go back and read scaffold.
Yeah looks like it still works as well.
And we no longer have any reliance upon that outside module.
And so like I said we can update all these version numbers on the fly to fit the schema of version numbers
being used by this outside service which we might not actually have control over.
Now last thing on you mentioned here is that although I am not receiving any errors you still might
not believe that all the data is being saved correctly so as a last little step let's figure out how
to reach directly into our orders Service database.
We're gonna figure out how to reach directly in there take a look at the tickets collection and just
make sure that these this ticket is being saved with the appropriate I.D. so to reach into the orders
service and look at some information inside of it.
We're going to open up a new tab inside of our terminal.
We're gonna do a cube CTF get pods and we're gonna find a pot that is running our orders Mongo D.B.
instance to mine yours is gonna be named very soon to mine all the orders Mongo devil and then some
long idea after it we're gonna copy that name and it will execute keep Seitel dash I.T. then the pod
name and then Mongo at the very end.
So this is going to execute the command Mongo inside the container inside this pod and that is what
it's going to open up the Mongo shell where we can then start to run some queries directly against the
Mongo DB database and I misspelled cube CTO excuse me I missed the actual command inside of here that
was my mistake UCL I.T. exact or exact I.T..
There you go.
Then the name then Mongo by mistake.
That's better.
So once I run that I now have my Mongo shell and I could start to run some commands against my Mongo
database.
Now we are gonna have to do one or two little administrative commands inside of here.
We're going to first list all the Ds that exist inside this database.
So there's our orders database.
That's what we want to actually connect to and run some queries inside of.
So we'll write out use orders and now we can write out DV tickets and that will access the tickets collection
inside the orders database.
So again the entire idea here is I want to try to find the ticket.
We had just created a moment ago and updated twice and just make sure that it has the appropriate versus
no price and so on make sure all the stuff is actually being saved correctly so to do so I could run
DV dot tickets dot find and I'm going to try to find a ticket with a price equal to whatever you had
last set inside of here.
So for me it's a price of two thousand
I'll run that and then I'll see all the tickets that match that particular price.
If you get too many records right here just make one more update to your ticket.
Give it a very unique price.
Maybe something like 1 9 8 two point three.
I don't know then enough that update and now that you've got a much more unique price you can run that
query again with 1 9 8 two point three so we'll see.
Now inside of here that we've got the aversion all set up correctly.
It has been incremented by 1 every single time and well it's got the exact same functionality more or
less as the module that we have been using previously.
The update if current plugin.
That's pretty much it.
That is how we would implement this stuff on our own if we were using some kind of versioning schema
that was not the same as the one that is assumed by this plugin.
Again this is most relevant if you're starting to get some events from some other service that uses
a very different kind of database where maybe maybe it's not even using versions in the hundreds.
I don't know of any database that does anything even remotely like that.
I just wanted to know that this was an option what might be actually kind of relevant or appropriate
is if there's some other versioning system where they don't start at version of zero near the first
version has a version of one instead.
That would have a different schema for versioning than this plug n and potentially things could start
to break.
OK.
So.
Enough talking again this is just kind of optional stuff just for something for you to know on the side.
I am going to undo all the changes we are going to stick with this plug in not the best assumption not
the best thing to use.
Like I said we're kind of cheating here.
Nonetheless I'm going to make use of it nonetheless get I'm going to delete the middleware dice but
together I'm going uncommon the plug in
I don't think there are any other changes we made inside of here.
So I'm going to save this file I'll then go back over to the listener and no longer are we going to
copy that version number over they'll delete where we were pulling version of data and make sure I do
not set it on the ticket anymore looking to save this and I'm going to go and make one last test inside
a post man just make sure everything still works as expected I'll change my price this time to about
1 0 three point three send that off I'm now on to version four and so I'll go run a quick query inside
of Mongo to be at once again one two three point three Yep version four.
Fantastic.
So we just swapped back over to that plugin and everything's still worked as expected.
Pretty awesome.
Yeah.
So again just option a little video.
Hope you enjoyed it.
Let's take a pause right here and continue with our app in just a moment.