Share
Embed
Domain Driven Design with MongoDB - Chris Hafey, On Point Medical Diagnostics
MongoChicago 2011
mongodb
November 02, 2011
Transcript
35 slides
-
Domain Driven Design with MongoDB Chris Hafey
[email protected] CTO, OnPoint Medical Diagnos@cs -
Domain Driven Design Overview Challenges Interes/ng
Pa1erns Persistent Wrapper Repository Service Pub Sub Queueing Blob Storage -
Communica/on Challenges? Business Folks Tech Folks Scalability
Cloud NoSQL Stock Price Customers Cash flow Sales HTML5 -
Ports And Adapters Architecture Service Side API Applica@on
+ Domain Mock MongoDB Adapter Adapter Adapter Adapter -
Ports And Adapters Architecture Service Side API Applica@on
+ Domain Mock MongoDB Adapter Adapter Adapter Adapter -
All problems in computer science can be solved by
another level of indirec6on -‐ David Wheeler -
Services En@@es Value Objects Repositories Factories
Domain Building Blocks -
Value Objects Have no iden@ty Usually immutable
Can own child value objects Address Price Color GeoLoca@on -
En@@es Have a unique iden@fier Have behavior
Own child value objects Order Line Bank Account Withdrawal Pa@ent Visit -
Aggregates Order Bank Account Pa@ent Record
Have a unique iden@fier Have behavior Own child en@@es -
Challenges Why are we doing ORM? Why
is my database load so high? Where does behavior go? -
Why is my database load so high? • Domain
Models tend to be normalized -‐> Denormaliza@on is the black art of RDBMS • DBAs not involved in the domain model design • Extra work required to interact with individual en@@es managed by aggregates Order Customer OrderLine1 Insert Order OrderLine2 OrderLine3 OrderLine4 OrderLine5 Insert OrderLine Insert OrderLine Insert OrderLine Insert OrderLine Insert OrderLine -
MongoDB FTW! Insert Document Order Customer
OrderLine1 OrderLine2 OrderLine3 OrderLine4 OrderLine5 • MongoDB’s document orienta@on eliminates the need for denormaliza@on • Complex object graphs s@ll result in a single read or write to the database -
Value Objects None – They are immutable!
En66es State modifica@on logic Repositories CRUD, Simple Queries, Schema Versioning Services Complex behavior related to mul@ple en@@es or other systems Where does the behavior go? -
Persistent Wrapper Wrapper class for pure domain model aggregates
-‐ Has the MongoDB ObjectId -‐ Defines the type -‐ Schema Version -‐ Created and Updated TimeStamps -‐ Created and Updated User Ids -‐ Aggregates the domain model en@ty -
Repository Responsibili@es: CRUD Simple Queries
Schema Version Logic -
MongoDBRepository<User> +Create +Get +Update +Delete
+FindAll IUserRepository +Create +Get +Update +FindAll UserRepository -‐FromUserV1 User +Login +Password +Name +LastLoginTimeStamp UserV1 +Login +Password +Name <<extends>> <<implements>> <<depends>> <<depends>> Repository -
Repository Things to consider: 1:1:1 –
domain model aggregate -‐> repository -‐> collec@on Create a base repository class using generics Create separate concrete classes for each schema version Use a reflec@on driven automapper Create a separate service to handle more complex opera@ons -‐ Keep repositories simple! -
Service Domain Services: Complex opera@ons spanning mul@ple
aggregates e.g. Algorithms, merge, split Infrastructure Services: Communicate with outside world via adapters e.g. Complex opera@ons spanning mul@ple repositories -
Service Things to consider: Talk directly
to MongoDB for complex transac@ons -‐ Queries spanning mul@ple collec@ons -‐ Modifica@ons to mul@ple documents -‐ Map/reduce Leverage repositories when possible -‐ Keep repositories simple -
Pub Sub Queueing Things to consider: Implement
Pop using FindAndModify for single consumer For mul@ple consumers, use documents as changelog entries -‐ Include a @mestamp in the document so each consumer can keep track of what it has seen Reuse repository func@onality Periodically purge old entries in batch Separate collec@ons for each queue -
Blob Storage Responsibili@es: CRUD for binary large objects
Things to consider: Use GridFS! Make Blobs immutable so they are idempotent -‐ Use internally generated id for filename -‐ Two phase write – local disk first, then GridFS Make GridFS filenames self describing -‐ Embed type on end of filename -‐ Embed encoding as extension (.gzip, .zip, etc) Use GridFS metadata to further describe blob Store GridFS filename as an ajribute of a domain model en@ty -
Blob Storage ImageUpload <<REST Service>> <<Local Disk>>
MongoDbFileRepository <<implements>> IFileRepository <<mongodb>> 2) writeImage(filename) <<Domain En@ty>> 3) create(filename) 5) GridFS.Upload 1) Generate unique filename Image +GridFSFilename