Spring Boot Code Structure: Package by Layer vs Package by Feature

Поділитися
Вставка
  • Опубліковано 6 січ 2025

КОМЕНТАРІ • 66

  • @benderbg
    @benderbg Рік тому +5

    For a total beginner this video is packed with useful information. Thanks for explaining it in Layman's terms.

    • @DanVega
      @DanVega  Рік тому +2

      So glad that you found this useful, thank you!

  • @JohnTriantafillakis
    @JohnTriantafillakis Рік тому +24

    Dan, it would be great a demo with a comparison of Hexagonal architecture ,Layer, Package

    • @DanVega
      @DanVega  Рік тому +4

      We are working towards that...one step at a time.

    • @praveens2272
      @praveens2272 Рік тому +5

      Hexagonal architecture just makes unnecessary complexity to your project.

    • @BingyangWei
      @BingyangWei Рік тому +3

      In my latest Spring Boot 3 tutorial, I adopted the "Package by Feature" approach. In my old Spring Boot 2 tutorial, for the same running example, I used the "Package by Layer" approach.
      If you are interested, please take a look. Feel free to provide any feedback.

    • @ismile47
      @ismile47 Рік тому

      @DanVega waiting on the above request. Just a reminder. That will be really helpful for community as there is so much of confusion around this concepts which and how to use.

  • @_leftii
    @_leftii Рік тому

    Love it! I was iffy about posing this question in office hours a few months back, but after seeing how much engagement there is on this video I'm so glad I did and am not the only one that was interested!

  • @sarkar_957
    @sarkar_957 Рік тому +2

    Killing it... always love to watch your videos 😉

  • @houn-x
    @houn-x Рік тому +1

    This was very useful. You've just gained a new subscriber in me!

  • @Sunil_Veeramuthu
    @Sunil_Veeramuthu Рік тому

    Thanks, Dan - this is very insightful as always!
    Aside from just sounding right, generally speaking, the biggest upside for me is the ease with which you can fork out a microservice when packaging by feature (and maybe modularity to a certain extent). That is a good litmus test on how cohesive and less coupled your code is.
    But then, you don’t create new projects every day, so you’re basically stuck with whatever the original authors intended, and that’s usually packaging by layer.

  • @FahadAli-km3ll
    @FahadAli-km3ll Рік тому +9

    Hi Dan. Thank you for another great video.
    I clearly see the benefits of the package by feature approach. However, I am wondering what your opinion is on implementing relationships between the entities. For low coupling I imagine that every package would only have one single point of entry for other packages (e.g. a service or interface exposed to be used by other features). In which case how would you go about designing the relationships between the entities? You ofc won't be able to leverage the Spring Data JPA annotations so I guess you would create DTOs between the features (which, in my opinion, may introduce unnecessary complexity depending on the size of the project). And maybe just storing the id of the referenced entity? Is some leakage acceptable?
    Let me hear your opinion, thank you! :)

  • @tonydeveloperdndndn
    @tonydeveloperdndndn Рік тому +2

    Short video but proving the good overview. Thanks for that.

  • @Anveshana837
    @Anveshana837 Місяць тому

    Dan, thanks for the video, it was helpful.

  • @DavidSoles
    @DavidSoles Рік тому +4

    Good video. Thanks for making such useful videos

    • @DanVega
      @DanVega  Рік тому +2

      Thank you for watching them David!

  • @static-m-s
    @static-m-s Рік тому +3

    Great article/video! Thank you!

  • @cbmeeks
    @cbmeeks Рік тому +8

    I packaged by layer for years. Until I saw some people packaging by feature and I thought that was a crazy idea. Until I tried it myself. I found package by feature is very nice for large projects. No going back for me.

    • @DanVega
      @DanVega  Рік тому +2

      Thanks for sharing!

  • @darkogrozdanovski
    @darkogrozdanovski 11 місяців тому

    I generally work by packaging by feature and then layers within as you mentioned at the end. In my code each feature module stays quite compact but the additional layer packages give me a bit of structure and make it easier to navigate the code. Its usually up to 20 files per feature, 2-3 services, 7-10 use case interfaces, entities, DTO-s for Inputs and outputs, filtering etc.. I think the boundaries between features are clear and not an issue at all even though i lose the package visibility benefit of packaging by feature in a flat package.
    What i really struggle with is having Data JPA relationships having references to other feature entities. I feel like Data JPA is not well suited for this way of structuring code, or I am not using it correctly.
    So as an example in sports, having a "Matches" Feature, and a "Teams" feature, where a match references a team, but a team is also standalone. So if i just use teamId in match its really hard to query (lets say i want to get a list of matches filtered by a specific team), so i have a JPA OnetoMany relationship there.

  • @JimShingler
    @JimShingler Рік тому +1

    Really great explaination!

  • @grenadespoon
    @grenadespoon Рік тому +5

    In package by feature, would you put a security config into a config package, or a security package? What about a controller advice?

  • @fredericolivier7896
    @fredericolivier7896 Рік тому +8

    I do package by feature 100% of the time.

    • @PeterSarazin
      @PeterSarazin 3 місяці тому

      What is the best way to structure junit tests with package by feature?

    • @SouthernRedneck-pn5pd
      @SouthernRedneck-pn5pd 17 днів тому

      @@PeterSarazinthat would be exactly the same package structure, not matter what architecture you use. The test should match exactly the same.

  • @asterixcode
    @asterixcode Рік тому +1

    what about a package strucuture with 4 main packages: api (containing other packages such as controller, mappers/assemblers, listeners), domain, core, infrastructure? Then the tradicional layer package within domain, core and infra?

  • @ashishsengar87
    @ashishsengar87 Рік тому +1

    Great video

  • @USONOFAV
    @USONOFAV Рік тому +1

    If you doing monolithic apps package feature is more maintainable for microservices package by layer.

  • @danieldiaz6025
    @danieldiaz6025 Рік тому +4

    I generally prefer package-by-feature. But: I also like API-first development (generating controller interfaces using OpenAPI Generator for example) and I feel it clashes a little with the package-by-feature approach, because you generate an entire "layer" (the controllers) in one go, and all the results tend to be put in the same package. Is there a solution to this apparent tension?

  • @DHA508
    @DHA508 Рік тому +1

    Thanks Dan

  • @scerrisebastien
    @scerrisebastien Рік тому

    Very interesting discussion indeed. If a service A need a service B datas to build a response, how you handle this in feature design. You need to keep public accessor, is n it ?

  • @aziztolearn
    @aziztolearn Рік тому +1

    Shouldn't we call packages plural like controllers, models?
    Or that's just up to us to call model or models?

  • @egonsaks
    @egonsaks 3 місяці тому

    How do I get the spring tool on the sidebar so I can see what spring beans are in application context?

  • @cviniciusm
    @cviniciusm Рік тому +3

    I think your article lacks the "comment" implementation to make clear the boundaries of layer vs feature, to show us how comment and post will relate to each other.

    • @DanVega
      @DanVega  Рік тому +1

      Agree that can also be a discussion on DDD

  • @kacpergrabiec
    @kacpergrabiec Рік тому

    What do you think about multi-module approach?

  • @alpsavasdev
    @alpsavasdev 5 місяців тому

    I also like this approach the best but I have a question. When I access from a service in one package to another service or a repository etc. in a different package, is that OK?
    My second question is is there a resource like a book or video series or something similar to learn more about this approach in more details?

  • @danielcommins1285
    @danielcommins1285 Рік тому +1

    Coupling between layers can be mitigated by interfaces, no?

  • @thebest-cr2sb
    @thebest-cr2sb 7 місяців тому

    is it possible to do a packaging by layer inside the features , in my case i have a lot of DTOs and and sevral repositories since the feature containe many entities , and i want to know is it correct to split them by layers inside the feature package ?

  • @geni4551
    @geni4551 Рік тому +1

    Just the GOAT

    • @DanVega
      @DanVega  Рік тому +1

      You just mae my day!

  • @Geniusmayor
    @Geniusmayor Рік тому

    How will test be written if the classes are not public in the package by feature version?

  • @iishanto
    @iishanto 9 місяців тому +1

    What should be done when a model in a feature package has a relation with other models outside of the feature package, such as when a Post model has a relation with a Comment model? Is there any way to handle that?

    • @SouthernRedneck-pn5pd
      @SouthernRedneck-pn5pd 17 днів тому

      Shared classes are going to have a public access and moved to another package within other feature packages, like a common.

  • @davidleonardobernal61
    @davidleonardobernal61 Рік тому +1

    Hi Dan,
    In a scenario where the API-First methodology is employed, and we have an openapi.yml file representing all the operations of our API (in this case, the blog API), I understand that in the case of a layered architecture, we would typically have a BlogController where we implement all our methods. However, in the case of adopting a feature-based architecture, would we create a separate openapi file for each feature, where the specific functionality is implemented? Or would we follow a similar approach as in the layered architecture by sharing this interface among all the features in some way?

    • @SouthernRedneck-pn5pd
      @SouthernRedneck-pn5pd 17 днів тому

      Application specs are typically in one file with multiple endpoints. That file doesn’t have to be in the repo at all if there is a dedicated place for the specs of the services.

  • @grenadespoon
    @grenadespoon Рік тому

    Thanks for doing this

  • @PeterSarazin
    @PeterSarazin 3 місяці тому

    What is the best way to structure junit tests with package by feature? Are there any examples of this?

    • @SouthernRedneck-pn5pd
      @SouthernRedneck-pn5pd 17 днів тому

      There is nothing special. Unit tests are still match the package structure and each test class would test each class with some non-trivial logic. I see some devs are testing getters, which is out of my mind…

  • @mrngwozdz
    @mrngwozdz Рік тому

    I am mixing both types. I found that keeping packages such as: configuration, entities, controller, dtos, and mappers as "Package by Layer" works well, but I organize all services in the following manner:
    services
    ---- product
    -------- business
    In this package, you can find our main code. Everything we have to write manually, come up with, etc., is because it's business-related. This package should also be tested 100% by unit tests.
    -------- data
    Here we have a package where we can find all the classes from which we obtain data for a product. We can source this data from databases, external services, etc. There is no logic; the primary responsibility is simply to retrieve raw data from external sources.
    I find this structure the most readable. I disliked searching for controllers or entities using "Package by Feature". On the other hand, writing clean code with tons of business classes in "Package by Layer" is not possible, or at least I've never seen it done.

  • @bittu0836
    @bittu0836 Рік тому

    thankyou sir of such contents

  • @ogyct
    @ogyct 9 місяців тому +1

    This all makes sense until we begin doing something more complicated. Let's say we have Authors, who write the posts. Naturally we want our entites to have relations. This way we no longer can make entity classes package-private. We also create coupling. In the end, the whole idea of package by feature becomes not viable. At least not in the way presented in the video. In my experience module will always contain all the stuff, which is related to each other in some way. An we come back again to package by layer. True modularity is possible only on not related stuff. e.g. i18n module for our FE.
    What do you think about that?

    • @tyleredmonds210
      @tyleredmonds210 Місяць тому +1

      This was my thought originally too. But if we look at the "loose" wording for coupling and not the fact that it's "no coupling", I think we can make an argument that some features can be coupled. In your example, if we had an "author" we might also have some other higher level models like "user" or "settings" or something like that. We could easily make a "top_level" package as a "feature" that contains these items.
      So say we now have a feature packaged app as follows, we still have loose coupling overall. Only the top level package is coupled to other packages. Auth doesn't care about post at all. So our structure isn't completely coupled, it's just loosely coupled.
      |-> post
      |-> postModel
      |-> postService
      |-> auth
      |-> authModel
      |-> topLevel
      |-> userModel
      |-> settingsModel
      |-> authorModel
      If we ever want to break this out to a microservices pattern in the future, we would be able to fairly easily. The top level package can become a service on it's own, while auth and post get pulled out as well.
      As you mentioned, in complex environments, you need SOME level of coupling. The Design Principle is to limit that coupling as much as possible.
      (this is an example I came up with in 10 seconds while reading comments on this post, please do not read explicitly into it. I'm just using it as an example of the thought process)

  • @ChristopherWarmbold
    @ChristopherWarmbold Рік тому

    @DanVega Could you also make a video comparing java packages vs maven modules when structuring your application

    • @tav1119
      @tav1119 Рік тому

      the only advantages of having maven modules are if you have different teams taking care of the same software. Usually a maven module project is bundled to only one jar or war.

  • @youtuger
    @youtuger 6 місяців тому

    i have to try package by feature one day. But i wonder what happens when i have 50 domain objects for different services

    • @SouthernRedneck-pn5pd
      @SouthernRedneck-pn5pd 17 днів тому

      Common or if used in multiple services, then a dedicated library, then pull that as a dependency.

  • @buksvdl
    @buksvdl Рік тому

    Code explosion. All classes except for the Service differ(almost) only in name. Should they even exist?

  • @UditSharma124
    @UditSharma124 Рік тому

    Great Explanation!!
    What about Global Exception Handler and Security configurations in package like feature structure?

    • @BrownBearMY
      @BrownBearMY Рік тому +2

      I'd usually store them by according to their scope. For example, I keep Global Exception Handler under web package as it's about translating Exceptions to HTTP status.

    • @SouthernRedneck-pn5pd
      @SouthernRedneck-pn5pd 17 днів тому

      These are part of configuration for the application, they all can be package private, if too many classes clogging the configuration package, then regroup them inside of the configuration.

  • @majidhajric1871
    @majidhajric1871 Рік тому +1

    Thanks for video but too much time spent on explaining package scanning.
    I have been worked on different projects and can say that if there is a shortcut, good lazy developer will take it.
    Using any of mentioned approaches without discipline will sooner or later lead to spaghetti code and dependency mix.
    Personally, hexagonal architecture seems like overhead at the beginning but it puts constraints and at the end there is benefit from it.
    All the best!