Guide on how to implement Clean Architecture in Next.js

Поділитися
Вставка

КОМЕНТАРІ • 142

  • @nikolovlazar
    @nikolovlazar  2 місяці тому +4

    Update: I refactored the app and now we're running on any runtime, including Vercel's Edge (hello middleware)! Check out my latest video to see the refactoring: ua-cam.com/video/Yliaah4oiZY/v-deo.html
    This is the definitive guide on how to implement Clean Architecture in Next.js. It's almost an hour, so grab a coffee or tea and dive in. Hope you enjoy this video! Some of you pointed out that using Sentry directly is breaking CA’s rules, and you’re right! I had to take a shortcut there, but I forgot to mention that in the video. If you have any questions, don't hesitate to reach out to me in the comments, or in my Discord server: creatures.sh.
    🔗 Links from the video:
    👉 GitHub Repo: github.com/nikolovlazar/nextjs-clean-architecture
    👉 Demo: next-clean-arch.vercel.app/
    👉 Clean Architecture article: blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
    👉 My interpretation diagram: app.eraser.io/workspace/fAyjQlkBiC7AoAoYoPnw?origin=share
    👉 Configure Inversify in Next.js video: ua-cam.com/video/2NVYG5VDmwQ/v-deo.html
    👉 Test case naming guide: www.epicweb.dev/talks/how-to-write-better-test-names

  • @carlpahuyo4482
    @carlpahuyo4482 2 місяці тому +8

    I'm a self-taught developer so I only really get these types of knowledge from tutorials or just follow how these techs' documentations do it. I've watched and read different tutorials about good and clean architecture to follow but most of them are just really opinionated and not really explain why. But THIS particular video really got me. It's clean and each type of file makes sense and does different isolated work. I think I'll implement this architecture in my next projects. I mostly use Supabase and I'm excited as to how I will implement this architecture with that tech :D Thank you so much for this video!

    • @nikolovlazar
      @nikolovlazar  2 місяці тому +4

      I'm glad you fount this useful! Here's an other project of mine that implements CA with Supabase: github.com/nikolovlazar/bife

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

    Bro, you saved my life! I'm struggled importing the reflect-metadata on NextJS all the time to implement dependency injection!

  • @0xmetalogica
    @0xmetalogica 2 місяці тому

    Fantastic video. I’ve been searching for a pattern to help me apply domain driven design properly to next JS projects and this example is the inspiration I needed. So comprehensive!

  • @steventabango4790
    @steventabango4790 2 місяці тому

    Thank you so much for this great video. I always heard about Clean Architecture and watched several videos, but I never truly understood it until now. After watching some videos that left me confused and even fearful of applying it, this one finally gave me a clear understanding to move forward. I love that it was demonstrated using Next.js because that's exactly what I'm learning.

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      Thank you! I'm glad that you found it useful!

  • @werix_4776
    @werix_4776 2 місяці тому +5

    Having this clean architecture as boilerplate to start a new complex project, I think would be cool, with different packages like supabase etc

    • @nikolovlazar
      @nikolovlazar  2 місяці тому +2

      Definitely! I think the GitHub repo is simple enough that it potentially could be used as a boilerplate, but feel free to fork it and swap out the libraries you need.

  • @kanogl
    @kanogl 2 місяці тому

    @nikolovlazar Amazing stuff... The bit on the presenter was a great thing to learn, security, ui friendlyness and performance from not shipping extra packages.

  • @didholipyan8227
    @didholipyan8227 2 місяці тому +11

    My brain is currently stop working🤯

  • @drosi1994
    @drosi1994 2 місяці тому

    One of the best and insightful videos that I have seen the last years in YT. Thank you man!

  • @harshitsahu8704
    @harshitsahu8704 2 місяці тому

    Thanks for creating it. It blows my mind. Need such content more on your channel.

  • @dunkpolice
    @dunkpolice 2 місяці тому +2

    По случайност ти намерих канала, точно преди седмичният stand up 😂 Keep up the quality content 👌

    • @nikolovlazar
      @nikolovlazar  2 місяці тому +1

      Thank you! Благодаря ви!

  • @KingDebo-rm7gj
    @KingDebo-rm7gj 2 місяці тому

    Haven't watched the entire video yet but the diagram alone was SUPER helpful and needed, Thanks a lot. Wish I could give you multiple likes

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      Thanks a lot! Happy that you found it useful!

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

    this is what quality content look like. thanks!

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

      Thank you! And thank you for becoming a member! 💖

  • @kiddienoob
    @kiddienoob 2 місяці тому

    Very clear explanations!
    A possible improvement:
    Instead of binding a test setup to the concrete implementation of your application's signInUseCase, you could create a wrapper for your tests like ```function authenticatedUser(): {sessionId: string} { return { sessionId: signInUseCase({user, password}).sessionId }```. That way if the meaning of what authenticated user actually is ever changes, you don't have to change it in all the test files.
    It's a bit abstract with a simple example like this, but it will make more sense when you are testing behavior that depends on a certain application state. For example: If you want to test that deleted todos cannot be updated, then you will have to first create one, then delete it, and only then you can test for what you are actually interested in. Here you could have a deletedTodo() function that takes care of that setup

  •  19 днів тому

    This is pure gold. Thank you so much!

  • @cesar-brandon
    @cesar-brandon 2 місяці тому +1

    Great video, I needed it ✨, I would like to see it in a more committed project but it still helped me, I still don't understand clean architecture so I will come back again

  • @Evyweb
    @Evyweb 2 місяці тому +1

    Not finished the video yet but as someone using clean architecture and tdd most of the time I can say that you did it pretty well. You can also enforce these principles for new developers or for bigger teams with ts-arch.

    • @nikolovlazar
      @nikolovlazar  2 місяці тому +1

      Thank you! Someone on my live streams told me about ts-arch. I checked it out, but haven't used it yet.

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

    Изключително добре направено! Браво!

  • @sasquatch_devs
    @sasquatch_devs Місяць тому +2

    Would love to see this applied for a React + Vite SPA application!

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

      That would be an interesting topic. CA on the client side!

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

    Awesome bro, we absolutely need more of this excellent content. subscribed for more of this! thank you!

  • @camchn3355
    @camchn3355 2 місяці тому

    Best Clean Architecture video ever, thank you 🙏🏻

  • @sidaliassoul408
    @sidaliassoul408 2 місяці тому

    Thanks for the great video lazar.
    Watched more than 5 streams then didn't have time to watch more glade that you dropped this one.

    • @nikolovlazar
      @nikolovlazar  2 місяці тому +1

      This video will save you HOURS 😂 thanks!

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

    Great video and explanation of each layer. I have one next.js specific question: should we prioritize server actions over route handlers? Are there any benefits to be gained from choosing one over the other?

    • @nikolovlazar
      @nikolovlazar  29 днів тому

      Thanks! Server Actions are faster to develop because they’re functions. Route Handlers are exposing an endpoint that can be triggered by any client, not just Next.js. I think when using Actions the app performs a rerender automatically to update the UI with the new data, so there’s that. If you’re building a Next.js app that will remain just a Next.js app (and not have other clients use your API) you can stick with actions. Even if you need to change in the future, you’ll just cut the try catch block that invoked the controller and refactor handling the return and exceptions.

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

    Thank you for the incredible amount of high quality information that you have packed into a hour long video! Very much appreciated 🙏 One question I would really like your opinion on and that is the choice for a DI library in TypeScript. You chose InversifyJS but there are others like TypeDI and tsyringe. All of them are not actively maintained for the past couple of years. Do you see any risks of implementing DI with these libraries, as is it part of the core of your codebase?

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

      Glad you liked it! And that's a good question! I think the only thing forcing the libraries to push updates (once they achieved what they want to achieve) is the language itself. As TypeScript / JavaScript evolves and introduces breaking changes, they most likely would need to push an update. That doesn't happen as often, so that's why you don't see any activity on these repositories for an extended period of time. On the other hand, just like any other library dependency, there is always a risk of deprecation and refactoring.

  • @shaked1233
    @shaked1233 2 місяці тому

    This is a very detailed video about clean arch, very well made. thanks

  • @IkraamDev
    @IkraamDev 2 місяці тому

    Great video. Extra respect for Neovim.

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

    Mind blowing. I wish I was a backend engineer I had hope to learn Architecruee stuff. I'm thankful I am Frontend Engineer, I should be disgrateful but Backend is OP.

  • @SushantJadhav-b5h
    @SushantJadhav-b5h 2 місяці тому

    Awesome video, could you please extend cover below things in second part?
    In Clean Architecture
    Where/how will handle global state like zustand or redux toolkit?
    Where/how will handle constants and enums?
    Where/how will handle language translation (for errors)?
    Where/how will use
    Where/how to map the types (separate types for Infra other layer)

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      Thank you! These are good points. I'll definitely cover some of these in future.

  • @PixeLabor
    @PixeLabor 28 днів тому +1

    very good viedo. thanks! :)

  • @vonghesjonovan
    @vonghesjonovan 2 місяці тому

    WOW!! So much bonus in that video!! Thank you so much!!! You made life easy for JS dev! 🔥🔥🔥

  • @baptiste.famchon
    @baptiste.famchon 2 місяці тому

    Thanks for this video @nikolovlazar !
    In your codebase (25:20) you talk about user authorization in use-case. So if we want to get more infos on user (free / paid on your example), we should retrieve the user repository and get user in this same use-case right ?

    • @nikolovlazar
      @nikolovlazar  2 місяці тому +1

      Correct! You can use the repository to retrieve the user object, and then you can use a service that implements the authorization check logic, so you can test that logic individually later.

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

    Great video. Quick question. Isn't the `getInjection` helper function an example of the service locator anti-pattern that InversifyJS warns against?

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

      I haven't read a lot on it being an anti-pattern, but thanks for bringing it to my attention. Looks like you're right. If you want to avoid it, you should either write everything as classes and do property injection, or export resolved services from within the DI and not the container itself. I haven't seen any issues of using the "getInjection" method in my app yet since implementing it, but I'll have this in mind. Thanks again!

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

    Thank you Lazar for your big efforts in this topic, your are using Lucia in this example, I'm struggling to do something similar with Next Auth, is there a good article/video about this approach?

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

      Thank you! Not sure if I’ve seen anything like that. Hop into creatures.sh and we can figure it out!

  • @ericmaina7922
    @ericmaina7922 2 місяці тому

    Very educative video. Create a larger project implementing the same

    • @nikolovlazar
      @nikolovlazar  2 місяці тому +1

      Thanks! It’s not a seriously large project, but I have it implemented here as well: github.com/nikolovlazar/bife

  • @yourr_dude
    @yourr_dude 2 місяці тому

    Maan thank you for your work. Greetings from Ukraine

  • @YevheniiViazovskyi
    @YevheniiViazovskyi 2 місяці тому

    Pleasant to watch bringing some order to usual Nextjs chaos. Really good ideas and realisation here.
    One thing i don't get fully is multiple controllers. Why is there createTodoController/getTodosForUserController/toggleTodoController (which acts like 3 different controllers) and not single TodoController with create/getTodosForUser/toggle methods?

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      Happy that you found it useful! In regards to the controller, you're talking about a class versus functions. Since we're in JavaScript, functions feel easier to work with so I went with functions. Classes need to be instantiated before you use them so it represents an extra step. If we utilized constructor injection for the DI, then we would've had to use a class.

    • @YevheniiViazovskyi
      @YevheniiViazovskyi 2 місяці тому

      @@nikolovlazar Thanks for the answer. Probably i'm just brain damaged by other MVC frameworks, hard to see a controller that is not an object 😅. The easiest way to avoid instantiation would be to have maybe index.js in the controller directory that reexports all functions in single object or single file that has only default export of an object containing all the methods.
      In theory static classes can also help to avoid instantiation but still allow extension. Some repeated logic (error handling for example) could live on the base Controller class. This will also allow to have decorators for methods, for example "Authenticatable" that could check sessionId and get the user.
      Thanks again for the content.

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      Oh that's a good point!

  • @matyascsoti4400
    @matyascsoti4400 Місяць тому +2

    QQ about input validation: Architecture wise ( looking good on a graph ), validation looks better in the controllers so both incoming ( from server ) and outgoing ( to server ) data is validated in the same place. But implementation wise validating your input data makes much more sense in the context of the form. Is the validation and form linked only by the form libraries, so its just getting used to it, or the proximity of the input to the form warrants its. Like you can validate the data without ever leaving the context of the form and calling a controller, vs calling the controller and returning the validation error in your onSubmit function and setting the errors explicitly from there ( as most form libs handle this explicitly ) ?

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

      Good question! In my other project, I reuse the same Zod schema on the client-side to validate the form as well. Validating input is a *must* on the server-side, because it's easy to jump around the frontend and send data directly to the server without passing the validation mechanism. Validation on the frontend is good UX, validation on the backend is good security practice.

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

      @@nikolovlazar Thank you for your time to response, I think I wasn't explicit enough with my question, the question was not 'to validate or not' but 'where to validate'. You validate your outgoing data inside your repository and sending back the validation error to the UI to handle it, most form libraries handle the validation in the context of the form and if the data is not valid it will never reach the repository ( repository call will never be reached in the onSubmit since the validation does not pass ). So my question is which one should be preferred as doing the latter feels good because of the proximity of the input to the form, the former makes sense in an 'architectural way' as the controller is the "gateguard" of the data 'correctness' of your application.

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

      No I think I understood you. You should validate on both sides. As I mentioned, form validation is good UX, but you have to validate in the controller as well for security reasons. Validating in both places is a good practice. With Zod, you can even share the same validation schema. Here's how I do that in my other project:
      - Form: github.com/nikolovlazar/bife/blob/main/app/app/collections/create-collection.tsx#L38
      - Controller: github.com/nikolovlazar/bife/blob/main/src/interface-adapters/controllers/create-collection.controller.ts#L6

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

      @@nikolovlazar lookin at the code indeed you are double validating your outgoing data, thanks for sharing, but now then I have to ask isn't double validating redundant? ( or it is in this case but there might be a situation when something can actually happen between your action and the controller, the current example is very straightforward you pass the validated data directly into your controller, where you validate it again, i am interpreting correctly )

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

      Double validation is not redundant. The backend and the frontend are two separate things that can live independently from each other, so each part handles validation for separate reasons. You could refactor it down the line and split it, or build a new client (ex. mobile app, AI client, whatever that uses the backend you already have) so you’ll have to refactor the server actions into api handlers. Even now, you can’t risk not validating the data on the backend, let alone in a scenario like that. Consider the backend and the frontend as two separate parts and validate data at both places. There won’t be any significant performance overheads as well.

  • @НикитаВолошин-ь1ь
    @НикитаВолошин-ь1ь 2 місяці тому

    Like, awesome! Please, more videos on architecture topic

  • @user-lt4tr2rm8q
    @user-lt4tr2rm8q Місяць тому +1

    Hey, this is super interesting... however what I'm struggling with, is that in this approach frontend and backend is completely separated, which I get is the idea of this paradigm, however in practice the lines are not always clear. For example lets say I build a tax return form: I might want all the business logic structured as presented to nicely handle a submitted form on the server side but still show the user an estimated value while they are filling the form which doesn't need (and I think shouldn't) be calculated in the backend for every changed value. Same with validation: If I'm already using zod and frontend libraries, I don't have to deal with validation and displaying errors... this is taken care of in the frontend. I still need to perform the same checks on the backend but ideally a non-malicious user only submits validated data once everything is in order. A model might be fine to import from the frontend and use as my validation scheme but the calculator example its not quite clear to me how I would deal with such a scenario and where I would put the code/helper methods which perform the calculations in the end in order to maintain separation and allow reusability without risking to import code that is only meant for the server side (which might e.g. leak secrets) on the client side.
    Any help/ideas would be greatly apreciated!

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

      Is the calculator logic plain javascript that can be used both on the frontend and backend? If it's something that you don't expect to change a lot, it's fine if there are two implementations of it (comments should note that as well). If not, see if you can isolate it in a shared function and how that would look like. You need to maintain testability, so try to follow the operation flow (contoller > use case(s) / service(s) > repository(ies)). You can have a use case that invokes the shared calculate function and use its output. That should be perfectly fine.

  • @iced2916
    @iced2916 2 місяці тому +1

    Using something like zsa would remove the need for input validation in the controller layer as it would be handled inside the action itself, maybe the session could also be validated inside the action and then the service would be called. This wouldn't be 100% compliant to clean arch because then the validation would belong in the framework layer and not in the interface adapters but It would be simpler to have the server action act as a controller

    • @nikolovlazar
      @nikolovlazar  2 місяці тому +2

      True! The issue with keeping that logic arises when you try to unit test that logic. Server actions should be plain functions in the test environment (haven’t checked though), but even if they are you’d have to handle ZSA-specific errors in your unit tests. If you ever need to refactor ZSA you’ll be in for a ride 😂

    • @iced2916
      @iced2916 2 місяці тому

      ​@@nikolovlazar Hey, I have another question, since drizzle is being used and we define all our database models there, in the entities/models the user definition is repeated and everytime we change something in the drizzle schema we need to go into the entites/models folder and change the zod schemas in order to match. I saw a library called drizzle-zod that allows zod schema generation from a drizzle table definition, maybe with this library we could define and export all the models and then in the application/entities/models we could have a class for the model and receive the it's model type in the constructor(coming from drizzle folder) and we could have access to all it's fields while also being able to define methods depending on the application's business logic. This way infrastructure concerns will be mixed up with application logic but I think this could work, what do you think about this approach?

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

      I did use drizzle-zod briefly in this project, not sure why I didn't even mention it. Models should contain a certain amount of logic in them as well, which are basically the zod schemas. The approach you described is definitely valid, but limited to models defining their own methods, and to potentially simpler projects. In a lot of cases you would have operations that modify multiple models (tables) so that's why the isolation happens between the "business logic" and the "business rules". Logic is use cases and controllers. Rules are the models. Bigger projects would have more model classes that depend on each other, so you're very likely to run into all sorts of issues like dependency issues. Not to mention, once you start bringing in other model classes in one model class, you're starting to create a "god class" (a.k.a. "god object"), which is a code smell and something you should avoid.

  • @MuhamadAzizPrasetyo
    @MuhamadAzizPrasetyo 2 місяці тому

    Very good stuff! Thank you

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

    Great content, thank you! I have a question regarding the sentry config included in your project. I have never used sentry, suppose i would like to do a code along with your tutorial, will a free sentry account be sufficient to apply the sentry features or is a paid subscription with them required ? Thanks!

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

      Glad you like the content! Yep, the free Sentry account supports all SDK features, except the Insights modules (business+) and Dashboards (team+), but you'll be able to get alerts, capture exceptions, measure performance and use traces for debugging without issues on the free plan.

  • @AndriusLau
    @AndriusLau 2 місяці тому +1

    basically a standard Rest API (repository, service, controller) plus UI :)

    • @nikolovlazar
      @nikolovlazar  2 місяці тому +1

      Pretty much 😁 with some additional rules on top

  • @hug0er96
    @hug0er96 2 місяці тому

    Awesome work, thank you for the video lazar. I have a question. How would you handle Prisma transactions in this code structure?

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      Thank you! Everything Prisma related would be boxed in a Repository.

    • @hug0er96
      @hug0er96 2 місяці тому +1

      @@nikolovlazar Thanks for the early response. But what if the Prisma transaction needs to occur across two different entities? For example: updating the user table to deduct credits and simultaneously decreasing the stock of a product purchased with credits. I understand that products will have their own repository, and users will have their own repository. However, implementing this logic in a useCase without introducing Prisma in application layer will not allow for a Prisma transaction, and each query will run separately, causing us to lose atomicity in the operation.

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      ⁠​​⁠that would be two different use cases. Use cases are single operations. Updating a field in the users table is one use case. Deducing credits in a different table is another. You’ll have a controller that “orchestrates” those two use cases based on the input, user, etc… the controller will invoke them.

    • @FTheohu
      @FTheohu 2 місяці тому

      @@nikolovlazar I am not the person you are replying to, but I assume you mean that the controller will combine those two use cases in a transaction and thus make the transaction atomic?

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      @@FTheohuoooh I see now. If that’s the case then I guess it has to be part of a repository. If those two or more db operations happen every single time, it does make sense to put them in one transaction in a repository and invoke that.
      Another approach I could think of is splitting the query building from executing. This is a wild idea and I’m just thinking out loud, but what if the repositories just build your query(ies), and then you pass it off to a service that executes all of them in a single database transaction? I’m not sure of what side effects can that have on testing, but it’s something to think about 😁

  • @zakir.nuriiev
    @zakir.nuriiev 2 місяці тому

    Thank you for the cool video! It was very interesting!

  • @issiagaconde
    @issiagaconde 2 місяці тому

    Thank you very much for the enormous effort you put into making this tutorial. I really like how you configure vscode. Can you share it with us? THANKS

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      Thank you! This is not vscode, but neovim. Here’s my config video: ua-cam.com/video/G7-qUMKSH_Y/v-deo.htmlsi=kq2lTPyJaQqa9JTl

  • @jekku123
    @jekku123 2 місяці тому

    Great video to explain clean arch! Im wondering that how to deal with stuff like internationalization etc that need middleware?

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      Thank you! I'm working on a different DI approach that would work in other runtimes and I'll most likely publish a separate video on it, so stick around for that one! Right now you'd have to patch things in the middleware function.

  • @galenus_0
    @galenus_0 2 місяці тому

    What nvim theme are you using?
    Also, great video 🫡

    • @nikolovlazar
      @nikolovlazar  2 місяці тому +1

      Thanks! It’s cyberdream with a custom background. Check it out here: My Neovim Dev Workflow
      ua-cam.com/video/G7-qUMKSH_Y/v-deo.html

  • @PeterStJ
    @PeterStJ Місяць тому +2

    Okay, nice explanation, looks great, only one thing bothers me, and it is a big big thing for me.. an __all__ layers you have the sentry calls.. on ALL layers. How does this fit into the clean architecture, clean maintainable code etc. I don't see it, sorry. Otherwise great explanation.

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

      Thanks! I had to take a shortcut there. It's not CA-approved 😁 We should put that away in its own service and call the service instead.

  • @soaacademy
    @soaacademy 2 місяці тому

    Thanks for the great work!

  • @viniciustomiokuboyama3706
    @viniciustomiokuboyama3706 2 місяці тому

    This is gold.

  • @seifmahdy4846
    @seifmahdy4846 2 місяці тому

    Great video!! I wonder how this can apply to TRPC specifically the T3 stack.

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      Thanks! Everything would fall into the Frameworks & Drivers layer. TRPC's queries (equivalent to Next.js Server Actions in a way) would be defined in the "app" directory alongside everything Next.js related, and they will invoke controllers. Exactly the same as the server actions I presented in this video.

    • @seifmahdy4846
      @seifmahdy4846 2 місяці тому

      @@nikolovlazar Thanks, this is really helpful!!

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      @@seifmahdy4846 You're welcome! If you have more questions don't hesitate to ask. I'm always around in my Discord server creatures.sh.

  • @Frim85
    @Frim85 2 місяці тому

    Love the vid, thnx!

  • @devyb-cc
    @devyb-cc 2 місяці тому +2

    zod for entities should be the norm hahah

  • @mhdyousuf3392
    @mhdyousuf3392 2 місяці тому

    At last, Thank you

  • @Deus-lo-Vuilt
    @Deus-lo-Vuilt 2 місяці тому

    Wow , thanks ❤

  • @kanogl
    @kanogl 2 місяці тому

    Hey mate, question on your errors entities you have a type called ErrorOptions but its not being defined anywhere in the code and i dont see it as imported from an external package, where does that come from?
    Thanks!

    • @nikolovlazar
      @nikolovlazar  2 місяці тому +1

      The "ErrorOptions" interface is built-in the language actually, just like the "Error" one.

  • @PixeLabor
    @PixeLabor 11 днів тому

    did you ever try to implement this in a bigger project? i recently tried it and it was so much over head creating all the dtos. and especially if you have nested entities it is just a pain doing this. and for one small change i need to touch a lot of files. this seems more like a academic philosphising about architecture. maybe if you have a big team. but not as a solo dev.

    • @nikolovlazar
      @nikolovlazar  9 днів тому

      I have a couple of shorts on my channel where I address this, but in short - yes. If you’re a solo dev and don’t care about testing or growing the team or the codebase, then you won’t see too much value in CA.

  • @DaveMacpherson
    @DaveMacpherson 2 місяці тому

    Are the objects returned by your presenters essentially DTO's?

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      Yep! Since you don't want to return entitie types, you create a UI-friendly object that contains the controller's results, which could be multiple entities as well. That's basically a DTO.

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

    Top!

  • @nekotajni394
    @nekotajni394 2 місяці тому

    Hey friend, I have an application with a large userbase, over 300k. I find that Sentry captures so many random JS errors that are unhandled and I have no idea why/what they do. It's like missing 'a' in some random js bundle, or scrollEvent, or some extension stuff. It consumes so many of my error metrics and it does nothing for me, what do you suggest I do in this case? I only want to capture relevant errors.

    • @nikolovlazar
      @nikolovlazar  2 місяці тому +1

      Hey! You should check out the Filtering doc: docs.sentry.io/platforms/javascript/guides/nextjs/configuration/filtering/
      You can try the "thirdPartyErrorFilterIntegration" method. That way you "fingerprint" your codebase's bundles and only errors that originate from those bundles get reported, otherwise they get ignored. This + the "ignoreErrors" regex can significantly reduce issues noise. Let me know if this works for you!

  • @PauloRodrigues-d9j
    @PauloRodrigues-d9j 2 місяці тому

    Which browser are you using?

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

    what theme is this in nvim?

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

      This is Cyberdream! github.com/nikolovlazar/dotfiles. I also have a video on my setup: ua-cam.com/video/G7-qUMKSH_Y/v-deo.html

  • @patolorde
    @patolorde 2 місяці тому

    Awesom

  • @zomars
    @zomars 2 місяці тому

    Can we hire you?

  • @yogithesymbian
    @yogithesymbian 2 місяці тому

    why we need sqllite instead mysql

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      I picked SQLite just to make the demo project simpler to run locally, no other reason.

    • @yogithesymbian
      @yogithesymbian 2 місяці тому

      @@nikolovlazar So if we use MySQL and hit an API, would it be challenging technically? Or do you have any suggestions?

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      Your codebase won't need to change too much (aside from your repository, which is the reason why you want to put away that implementation detail). If you want to use MySQL instead of SQLite, you'd need to start a mysql server alongside your app, and the easiest way to do that is to use Docker Compose. There's plenty of resources on how to get started with Docker and Docker Compose.

  • @starrynight72
    @starrynight72 2 дні тому

    It seems way too angular-like which I don't really accept when I work on nextjs this kind of framework based on react...

  • @김인욱-u5q
    @김인욱-u5q 2 місяці тому

    That's really cool, but it's also complicated :(

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      Step by step! It's important to understand the reasons why each layer exists, and why you want to split your app's codebase in layers.

    • @김인욱-u5q
      @김인욱-u5q 2 місяці тому

      @@nikolovlazar I watched this video without skipping anything. It helped me understand the structure, but the folder structure is too complicated and there are many libraries that I am using for the first time, so it is difficult to create a project from scratch and follow along. Still, I will try to follow along little by little.

    • @nikolovlazar
      @nikolovlazar  2 місяці тому +1

      @@김인욱-u5q A good rule of thumb is this:
      - if the library you use lives around the "consumer" part of the app (next.js, api handlers etc...) it belongs in the Frameworks layer.
      - if the library you use supplements the app's core logic (a database, auth, email service, APIs that your app uses...), it lives in the Infrastructure layer.
      It'll be either in Frameworks or Infra. There's no other place where you put third-party libraries.

    • @김인욱-u5q
      @김인욱-u5q 2 місяці тому

      @@nikolovlazar I'll keep that in mind. Thank you

    • @nikolovlazar
      @nikolovlazar  2 місяці тому

      @@김인욱-u5q Oh you meant there are many libraries in this video that you're using for the first time. Sorry I misunderstood your comment. Don't hesitate to ask me specific questions about the setup and libraries. If you want more real-time help, feel free to join my Discord server and we can discuss in there: creatures.sh.

  • @maxmurr
    @maxmurr 2 місяці тому

    First!

  • @MerthanMerter
    @MerthanMerter 2 місяці тому

    this is nesxt js

  • @ramirodondero7856
    @ramirodondero7856 2 місяці тому

    Genius!!!!!