Replies: 5 comments
-
Let's pin this to get more attraction, also shared it on twitter. Maybe @parisholley could give you some feedback, as he is adopting the library these days, and given the amount of issues he created, it looks like it is quite a large app :] You can also see some feedback in #296. I am not aware of anything really blocking/problematic, granted there are people complaining about things here and there (mostly those that never worked with data mappers in other languages), but usually it's nothing critical. Main issue I could see is schema diffing in v4, that lacks a lot of features and often produces additional queries (as it fails to compare some things properly) - but that is already addressed in v5. |
Beta Was this translation helpful? Give feedback.
-
I am still in the process of refactoring a GraphQL heavy application from TypeORM to MikroORM with about ~100 database tables and used just about every feature in both (except schema/migration support in Mikro). Here is my high-level criteria as to why you should choose MikroORM (or any Unit of Work style ORM) vs TypeORM/Sequalize/etc Evaluating SolutionsComplexitySimply put, TypeORM/Sequelize, those are "stateless" libraries. If you have the hydrated entity in a variable and you save it or otherwise tweak it, you can think of it as normal javascript and queries. A UOW approach is going to add another layer of complexity and if you are in a larger team, the likelihood of other engineers having experienced this type of library is very slim (UOW is a very enterprise concept mostly used in Java, .NET, etc). Most of the issues I've submitted to the project thus far are to help mitigate the risk associated with developers making mistakes. CleanlinessWhile a non-UOW library will be simpler to write code and understand, you still end up effectively writing your own UOW implementation without realizing it. Take this example below: async function callOne(em:EntityManager, author:Author){
author.name = 'Foobar';
await em.save(author);
}
async function callTwo(em:EntityManager, authorId: string){
const author = await em.getById(Author, authorId);
author.name = 'James';
await em.save(author);
}
async function delegate(em:EntityManager, authorId:string){
const author = await em.getById(Author, authorId);
await callOne(em, author);
await callTwo(em, authorId);
await em.save(author);
} When you have multiple developers working on the same code base, it is easier to have one author create callOne and another create callTwo, with someone eventually needing to reference both of those inside some delegate/higher-level service call. You can see from that example that with a non-UOW work, Granted, this example is rather plain/simple but the problem is exponential in a 100K line project. You effectively upfront have to commit to design patterns ahead of time:
Now if your app is simple and most of your database I/O happens in controllers without any real concept of a service layer, then this point doesn't matter. PerformancePersonally, this is probably the only reason why I would recommend UOW style libraries. If most of your mutations/controllers are at most traversing one-level down in a model (eg: author > books) or doing one-to-one inner joins, you aren't going to see much of a performance gain. Soon as you introduce mutli-level GraphQL queries or N+1 business logic, non-UOW libraries are simply going to bring your request response times to a crawl. typeorm/typeorm#3857 (comment) The issue above has been around for years and goes to show the prioritization of performance related issues in that project. This one particular problem just eats away at CPU time which in a single-threaded Node app is crucial. Most of my performances problems isn't queries, its inefficient library code. Schema/MigrationsJust don't :) TypeORM was full of bugs in generating diffs and its a game of whack-a-mole that no project will be able to solve effectively. Save pulling your hair out and just write SQL migrations your self. Ultimately, your going to need to do some database/dialect specific things at some point and it is easier to just get comfortable doing it manually. Why I Like MikroORMNote: These examples are pseudo code, API/names may be different Ergonomic Lazy LoadingMikro has a concept of "wrapped" types like "Loaded" Entitiesasync function callOne(books:Loaded<Book, 'author'>[]){
}
async function callTwo(books::Loaded<Book, 'genre'>[]){
}
async function delegate(em:EntityManager){
const books = await em.find(Book, {populate: ['author','genre']});
await callOne(books);
await callTwo(books);
} In the above call, I have two service methods which have their own data requirements. By using Flush Per RequestEvery time you call No Mutation RiskIn my first example, you can switch between passing ids or entities around without any risk of destroying transient data. This becomes more apparent when you have references to different entity relations (one-to-many), where you are constantly adding or removing elements in various service layers. Why Not Mikro?
If any of those are true, I would stick to another ORM. Otherwise, I think this project is a good enough state that I would not be concerned of any production-level issues for most projects. |
Beta Was this translation helpful? Give feedback.
-
Okay. I already anticipated most of these and I'm very glad that there aren't any integration issues that are connected to MikroORM ( most of the issues you mentioned are pros cons of DM/AR ). I will wait for the next major version and will experimenting with the migration. Is there a place you'd recommend where the ins and outs of the data mapper pattern are explained, because I see a lot of unfamiliar terms - not here, but in general, like persisting, flushing, auto-flushing at the end of a request? I do not feel confident in the understanding of how exactly the library works and I assume that using it that way will inevitably lead to some bugs or performance issues, so I'd like to familiarize myself as much as possible before diving in. Thanks a lot, both for the explanation and for taking a leap of faith implementing it into your project |
Beta Was this translation helpful? Give feedback.
-
your best bet is to look for information around Hibernate or JPA in enterprise Java as that is where a lot of these concepts originated (i believe). in particular, the concept of |
Beta Was this translation helpful? Give feedback.
-
We've been progressively migrating an application with ~100 tables from typeorm to mikro-orm, it's been going really well so far. Mikro-orm seems much more robust, is well documented, provides really nice features, among which:
So far we've not encountered any real issue (whereas on typeorm we encountered so many weird bugs 😅 ). On top of that, @B4nan is really very reactive on slack. The only downside I see is the fact that this library relies on a single person, which represents a risk. |
Beta Was this translation helpful? Give feedback.
-
I have been tracking the progress of this package almost since the start. Since I started learning more about backend architecture patterns, I was rather disappointed to see that a lot of the patterns used in other languages are hardly applicable in Node and one of the main problems was the fact that there was no good choice of an ORM following the DataMapper pattern. Without that, implementing business logic in entities instead of services becomes a lot harder and involves a lot more boilerplate.
As of lately I have been rather happy with the progress that you are making and also happy to see that there are people that have started contributing to the project and I'm thinking about possibly adopting it into the application that I'm working on.
Since Sequelize doesn't really deliver a good experience when working with hundreds of models, a migration to something more ergonomic is imminent at some point, and MikroORM is the only alternative, which seems promising as of now.
I'm planning to begin with an incremental adoption. We are currently using Sequelize and will likely use both MikroORM and Sequelize during the migration period.
Since the application is large and changes like these are time consuming and not that easy to implement, it would be in our best interest to make decisions carefully.
In that regard, I would like to ask you about any known, as of now, issues, bugs or flexibility limitations that may be problematic in larger apps, including performance.
If some specifics have been discussed or you have something in mind, I'd like to learn about it and where I can track its progress.
Thank you for the work that you have been doing.
This is also not addressed toward the official maintainers. If you are actually using MikroORM in a production application, I would really like to hear about the problems and hiccups that you were or are still having.
Beta Was this translation helpful? Give feedback.
All reactions