In "Database migration strategies" I show some thoughts on how to deal with database migrations. A podcast version of the channel can be found here: anchor.fm/fred...
i love that you mentioned you should create a DAO for abstraction. When I first started learning about backends, I would also just do direct database queries from the controller instead of having an abstraction. great video mate 🙌
At 8:43: How would you send an email to the users who haven't supplied an email? I think that could work for basically any other type of data but what do you realistically do for acquiring email info? Just delete them anyway after a few months? 😅 Also, in the case of name splitting into first and last, even if we assume the Western system where last name is last, wouldn't we have to split at the final " " to make it work for middle names? Some users would simply enter their first name if given the option, so would we have to say "not entered" or something for last name if there is no " "? What if last name is required in the new model? I agree with you, data migration seems hard. First I thought database migration meant changing from let's say MySQL to PostgreSQL. Great video on the topic of updating data
I'm also a bit curious about why you use a variable width font :) I'm always tweaking my editor config, but never really considered not using a monospace font. So I'm just curious about why you made the switch? Is it just to fit more text on the screen? Or did you notice some other benefits that you liked?
I appreciate the tip about the DAO abstraction, but how do you deal with having multiple relationships? I.e. a 'User' object, which has relations to Teams, Posts and Comments. You don't want to have all of those objects populate on EVERY query, but having a lot of different queries, i.e. 'getUserWithBlogById', 'getUsersWithComments' etc. also seems annoying. What's your view on I'd love to hear your take on this issue!
No, the state of REST does not mean that I am sending you the raw data I have in the database. That won't work since I may have data that I don't want to share with the client.
A better way would be publish an event called "UserQueried" . it contains the user details in the payload. The listener of this can update the names later. By doing this you are making sure that the GET API is doing one job perfectly. And it should fail for one reason. A GET API failing for not saving the updated user properly , violates Single responsibility principle. The listener can be built and tested independently. It can have all possible logic regarding update. If some exception happens in that listener, it is not going to impact the GET query. Once all users are migrated, remove the listener. Migration being done asynchronously is better strategy
If we use an async approach the client can update the record before the migration event and this may cause the migration event to overwrite the record with the old data. How can we handle this race condition?
I will spoil the answer in case someone wants to know. You will need a way to version the records that is either not time based or to a microsecond level precision. This brings us to the question, at what point is the benefit of following a principle costing us more than it is worth?
@@FredrikChristenson the race condition can be handled using optimistic locking technique. In an event driven based system, the events applied on the user aggregate will be done sequentially. Optimistic locking might not be supported by default. Theoretically that is the way to do.
So thorough, yet concise with no fluff. Thanks for this great vid!
i love that you mentioned you should create a DAO for abstraction. When I first started learning about backends, I would also just do direct database queries from the controller instead of having an abstraction. great video mate 🙌
At 8:43: How would you send an email to the users who haven't supplied an email? I think that could work for basically any other type of data but what do you realistically do for acquiring email info? Just delete them anyway after a few months? 😅
Also, in the case of name splitting into first and last, even if we assume the Western system where last name is last, wouldn't we have to split at the final " " to make it work for middle names? Some users would simply enter their first name if given the option, so would we have to say "not entered" or something for last name if there is no " "? What if last name is required in the new model? I agree with you, data migration seems hard.
First I thought database migration meant changing from let's say MySQL to PostgreSQL. Great video on the topic of updating data
What's the difference between DAO and Repository? They both seem so similiar.
You can most of the time think of them as different names for the same thing.
Really explanatory stuff. Impressive!
really aprecieated , straight forward just to tha point , cheers mate !
Whould you please explain WHY DON'T YOU USE A MONOSPACE FONT?
If you want some suggestion I am happy to suggest many awesome fonts :)
I'm also a bit curious about why you use a variable width font :)
I'm always tweaking my editor config, but never really considered not using a monospace font.
So I'm just curious about why you made the switch? Is it just to fit more text on the screen? Or did you notice some other benefits that you liked?
I appreciate the tip about the DAO abstraction, but how do you deal with having multiple relationships?
I.e. a 'User' object, which has relations to Teams, Posts and Comments. You don't want to have all of those objects populate on EVERY query, but having a lot of different queries, i.e. 'getUserWithBlogById', 'getUsersWithComments' etc. also seems annoying.
What's your view on I'd love to hear your take on this issue!
tag mongodg/mongoose somewhere in the description. There's so few tutorials on migrations with mongoose
More db-related stuff, please!
Aren't you breaking REST by performing a modification on a GET ?
No, the state of REST does not mean that I am sending you the raw data I have in the database.
That won't work since I may have data that I don't want to share with the client.
A better way would be publish an event called "UserQueried" . it contains the user details in the payload. The listener of this can update the names later.
By doing this you are making sure that the GET API is doing one job perfectly. And it should fail for one reason.
A GET API failing for not saving the updated user properly , violates Single responsibility principle.
The listener can be built and tested independently. It can have all possible logic regarding update. If some exception happens in that listener, it is not going to impact the GET query.
Once all users are migrated, remove the listener.
Migration being done asynchronously is better strategy
If we use an async approach the client can update the record before the migration event and this may cause the migration event to overwrite the record with the old data. How can we handle this race condition?
I will spoil the answer in case someone wants to know.
You will need a way to version the records that is either not time based or to a microsecond level precision.
This brings us to the question, at what point is the benefit of following a principle costing us more than it is worth?
@@FredrikChristenson the race condition can be handled using optimistic locking technique. In an event driven based system, the events applied on the user aggregate will be done sequentially.
Optimistic locking might not be supported by default. Theoretically that is the way to do.
great tutorial