Last active
December 12, 2015 07:59
-
-
Save kellabyte/4741078 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Struct Store | |
// | |
// Version 1: We may have written... | |
DocumentDatabase db = new DocumentDatabase(); | |
User user = new User(); | |
user.Id = 123; | |
user.FirstName = ....; | |
user.LastName = ....; | |
user.Bio = ....; | |
db.Put(user); | |
// Version 2: Two years forward... I want to add a Twitter handle. | |
DocumentDatabase db = new DocumentDatabase(); | |
User user = db.Get(123); | |
user.TwitterHandle = ...; | |
db.Put(user); | |
// But because I have 100 servers, I can't afford to take all 100 down at once to make | |
// this change. So I'm going to do what any highly available service does, | |
// run parallel versions. | |
// Scenario: The cluster is going through a week long rolling upgrade that will eventually | |
// upgrade the entire cluster. | |
// | |
// 1. User adds their twitter handle to their profile. | |
// 2. Version 2 of the service stores new User struct/class to document DB with the twitter handle. | |
// 3. User 4 days later decides to update their bio. | |
// 4. Version 1 of the service handles the request, modifies the User document. | |
// | |
// Because version 1 and 2 use class/struct serialization, #4 above lost the twitter handle. Gone. | |
// | |
// We took flexible document databases using an extensible data formats (XML/JSON) & ejected flexibility. | |
// | |
// This is what happens when we treat databases as extensions of our programming language. | |
// We lose the benefits of the data model the database provides because we tried to | |
// type everything to death. | |
// | |
// This is just one example of Stuct Store, not Document Database. |
@peteraritchie that's going to introduce some pretty complicated code (change tracking) to figure that out. A lot of complexity I would argue isn't required if we weren't trying to be so addicted to strict typing. A domain can be loosely typed.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Honestly, to push that level of knowledge into the code that calls Get/Put is a responsibility violation. The code that uses a User object shouldn't have to care about anything it doesn't need to know about. See (SRP and Interface Segregation). The "database" class (or a Repository wrapping it) should deal with that responsibility--it can be smart enough to know that despite having a UserV1 object that there's a bunch of other data that UserV1 doesn't contain but is in the database and assume a "Put" is an upsert.