Coder Social home page Coder Social logo

Comments (5)

Sairyss avatar Sairyss commented on May 17, 2024 2

That's right, you have to adjust either a type to accept only the parameters specified in prepareQuery, or modify Repository to your liking. I'll think how to improve it in the future so it's less confusing.

from domain-driven-hexagon.

Sairyss avatar Sairyss commented on May 17, 2024
  1. This is just an example to show that you can use TypeOrm repos if you have specific queries that can't be simply queried using this.findOne(). In this case either one works, choose any that you like more.
  2. prepareQuery is meant for constructing a query from value objects, since you need to extract values from them. In this example use case we allow querying users only by ID. If you want to allow querying users by, lets say, country, you'd have to add
if (params.address?.country) {
  where.country = params.address.country
}

Keep in mind that this is an example implementation and might not be the best solution for all use cases.

from domain-driven-hexagon.

estrehle avatar estrehle commented on May 17, 2024

Thank you!

To me it feels like in prepareQuery I would have to duplicate most of the logic from OrmMapper.toOrmProps, only that each line will be wrapped in a if (params...) { ... } clause. Maybe there is a way to re-use the logic from the mapper and use a more abstract if clause?

from domain-driven-hexagon.

Sairyss avatar Sairyss commented on May 17, 2024

The problem is that mapper requires all (or almost all) fields to be present to save the entity, but in a query all fields are optional. Also a query may have different forms, not just simple ones like discussed here. Here is an example of a prepareQuery from one of my projects:

      ...
      if (status) {
        receiver.status = status;
        sender.status = status;
      }
      if (params?.createdBefore) {
        receiver.createdAt = LessThanOrEqual(params.createdBefore);
        sender.createdAt = LessThanOrEqual(params.createdBefore);
      }
     return [sender, receiver];

As you can see this would be impossible to map just by using a mapper, since you can have operators in your query like <= or >=, or you may need to query in a joined tables (like sender and receiver in an example above)

from domain-driven-hexagon.

estrehle avatar estrehle commented on May 17, 2024

Ah, I see! Now I understand why one would want a more flexible way of preparing queries.

My worry, however, is that this implementation suggests a generality that is not there. The repository exposes a method

findOne(params: QueryParams<EntityProps>)

where

type QueryParams<EntityProps> = DeepPartial<BaseEntityProps & EntityProps>

To anyone who has not studied prepareQuery in detail, this looks like a method that allows one to search the repository using arbitrary combinations of entity properties.

But when I call, say, UserRepository.findOne({ country: 'Germany' }) then the country param will be silently deleted and the result will be the same as if I had called UserRepository.findOne({ }). That could lead to nasty bugs.

My "solution" was to remove the find... methods (except for findById, which works the same for every entity) from TypeormRepositoryBase and resort to custom implementations in each repository, in the spirit of UserRepository.findOneByCountry(country: string).

from domain-driven-hexagon.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.