Python FastAPI Tutorial (Part 8): Routers - Organizing Routes into Modules with APIRouter
20:13

Python FastAPI Tutorial (Part 8): Routers - Organizing Routes into Modules with APIRouter

Corey Schafer 18.01.2026 6 487 просмотров 399 лайков

Machine-readable: Markdown · JSON API · Site index

Поделиться Telegram VK Бот
Транскрипт Скачать .md
Анализ с AI
Описание видео
In this video, we'll be learning how to organize our FastAPI application using APIRouter. As our app has grown throughout this series, our main.py file has become long and difficult to maintain. We'll fix that by creating a routers directory and splitting our API routes into separate modules—one for users and one for posts. This is a common pattern in real-world FastAPI development and is similar to Blueprints if you're coming from Flask. By the end of this video, you'll know how to structure your FastAPI projects for better maintainability and scalability. Let's get started... The code from this video can be found here: https://github.com/CoreyMSchafer/FastAPI-08-Routers Full FastAPI Course: https://www.youtube.com/playlist?list=PL-osiE80TeTsak-c-QsVeg0YYG_0TeyXI ✅ Support My Channel Through Patreon: https://www.patreon.com/coreyms ✅ Become a Channel Member: https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g/join ✅ One-Time Contribution Through PayPal: https://goo.gl/649HFY ✅ Cryptocurrency Donations: Bitcoin Wallet - 3MPH8oY2EAgbLVy7RBMinwcBntggi7qeG3 Ethereum Wallet - 0x151649418616068fB46C3598083817101d3bCD33 Litecoin Wallet - MPvEBY5fxGkmPQgocfJbxP6EmTo5UUXMot ✅ Corey's Public Amazon Wishlist http://a.co/inIyro1 ✅ Equipment I Use and Books I Recommend: https://www.amazon.com/shop/coreyschafer ▶️ You Can Find Me On: My Website - http://coreyms.com/ My Second Channel - https://www.youtube.com/c/coreymschafer Facebook - https://www.facebook.com/CoreyMSchafer Twitter - https://twitter.com/CoreyMSchafer Instagram - https://www.instagram.com/coreymschafer/ #Python #FastAPI

Оглавление (4 сегментов)

Segment 1 (00:00 - 05:00)

Hey there. How's it going everybody? In this video, we're going to be learning how to organize our Fast API application using routers. Now, if you've been following along with this series, then you know that we've built up a lot of functionality. In tutorial 6, we added full CRUD operations for post and users. And in tutorial 7, we made everything faster with async and await. Now, before we add more features like forms and authentication, we're going to take a step back and organize what we have. So this is a common pattern in real world development. You build up some functionality, then you polish and organize before adding more complexity. So let's go ahead and get started here. So let me show you what I'm talking about. So we have our main. py file open here. And if I scroll through this, then you can see that this is already super long. So, we've got our imports, we've got our lifespan, we have our app setup, we have our template routes, we have our user API routes and exception handlers, all of that mixed together. Now, all of this works, but if we keep adding features, then this file would become a nightmare to maintain. So, in this video, we're going to reorganize using API routers. Now, if you've ever used Flask, this is similar to blueprints. So, we'll create a router directory and then move our user routes into one file, move our post routes into another, and then update main. py to include those. And when we're done, everything works exactly the same from the outside. So, the same URLs, same functionality. We're just improving the internal organization here. So, what is an API router? So, it's fast API's tool for organizing routes into modules. So instead of defining all of our routes on the main app object, we're going to define them on a router and then include that router in our app. So the basic pattern is pretty simple. In a separate file, we create a router with router equals API router. And then we define the routes using router. get and router. post instead of app. get and app. post like we have here. Then in our main file, we use app. incclude include router to connect it and that's going to give us a lot of flexibility and we can apply common prefixes to a group of routes, apply tags for documentation and keep related code together. Okay, so let's go ahead and get started and organize everything that we have here. So I'm going to create a new directory in my project directory here. And I'm going to call this routers. And within routers I am going to create this file that is double_anitouble_. py. And that file will make this a proper Python package. Now that's just going to remain empty. No code is needed there. It's not strictly required in modern Python, but it helps tools like liners and type checkers. So it's still a best practice. So now we're going to create two router files within this routers directory. So I will create a file here called users. py and then I will create a new file called post. py. And now let's start with our users route here. And I will get rid of the sidebar there. So first I'm going to add the imports. Now, another good thing about splitting these up is that we can add only the imports that we need for users instead of everything else that's currently in our main. py file. So, I've got these prepared in my snippets to save some time. Basically, I've just plucked out what's required for the users here. So, I'm going to grab all of our imports that are just specific to the users. Now one thing to point out here is that I also included this import from fast API called API router but we also have our database dependencies models and the schemas that we need. So now since this is a router I'm going to create our router instance. So I'll just say router is equal to and this will be API router and this is what we're going to decorate our routes with instead of our app. So now let's move the user endpoints from main. py py. Now, I think the best way to organize this uh what we currently have is to only move the API routes, which are the ones with the path starting with for/appi slash users. So, let me find those here. So, those start here. Now, I'm not going to move the template routes into our routers like the homepage, the post page, the users post page. I'm going to keep those in main. py. That way main. py can be for our front-end views and these API routers can be for our API routes. So let me just move over one API route for now and we'll see what changes. So I will grab uh this route here and paste

Segment 2 (05:00 - 10:00)

this in. So I've currently moved over our create user route. Now when moving these two things are going to change. So first instead of app. post post here that becomes router. post post that router instance that we created there. And second, the path is going to change here. Instead of forward slash API slash users, I'm just going to use an empty string here. Now, using an empty string might look a bit odd, but here's why we're doing that. So, the path in the router is relative. So, when we include this router, we're going to specify a prefix of for/appi slash users. So the router's empty string actually becomes that prefix of for/ API/ users. So let me just type this out so that you understand what's going on here. So in main. py we're going to create this with a prefix of for/ API slusers. So now within users py we're going to have an empty string here. So, whenever these are put together, it's going to end up with a route uh that just looks like this. Since this is an empty string, now if I was to put a forward slash here and then we would have a forward slash here, it would add to that prefix and then we would have a trailing slash there on the end. Now, having that trailing slash is fine, but I just don't want it. Uh, it can sometimes cause issues with like 307 redirects and things like that, but I like the empty string anyway. I like uh having those non-trailing slashes there. So, clean paths and also no redirects. But that is all that it takes to move a route over to a router. All we changed was this from app. post to router. post. And we changed this from/appi/ users just to an empty string. Everything else stays the same. We have all the async await stuff. We have the database logic. We have the validation. None of that changes. Only the decorator and the path. So now let me move the rest of the API user endpoints. And I'll grab them all at once here. So I'm going back to our file here. Now I've already moved create user. So I'm going to remove that. And now I'm going to grab from get user all the way down to delete user. So let me find that. And that's there. So I'll cut that out. I will paste this in to our router here. And we've already done this one here. Now I'm just going to change the rest of these. So this will be router. get. And instead of for/appi slash users, this is just going to be forward slash user ID. So we'll remove that prefix that we're going to add. And I will do this for basically every route. So there's not too many of these here. So I'll keep making these changes. And we have one more here. And this will be router. And that will be for/ user ID there as well. So let me make sure that I did all of those correctly. That looks good. And that looks good. So that's all of our user API endpoints that are moved o over to the users router. So now let's do the same for post. So I've already created this post. py uh within routers here. I'm also going to add the imports that we need from my snippets here. So let me copy this and within post. py I will add the imports that we need. Let me make sure that all those imports were used. They were okay. So this is a similar setup but with post related schemas and I also already have the API router instantiated here. Now I'll move all the post API endpoints from main. py. So it's the same pattern here. So from get post I am going to copy from here all the way down to delete post. So all the way to here we will cut those out and we will paste these in here. Go up to the top. And now I will go ahead and change all of these. This is going to be router. get. We are going to make this an empty string now because that is going to be our prefix. And we'll see what that prefix looks like here in just a second. Again, I will change that to router. Remove that. Change to router. Leave this forward slost ID there. That still needs to be tagged onto our URL. Router. Leave that forward/post ID. And

Segment 3 (10:00 - 15:00)

router here. And leave that forward slashpost ID. And this is the last one here. Router. Okay, so now we have all of our post API routes moved into this routers post. py. We have all of our user API routes moved into this users. py. Now let's update main. py to include these routers. So first I'll save that to do some auto formatting there. Now if we go to the imports, we can see that we're no longer using any of these schemas. So I'm just going to delete all of those. All of those schemas are now being used inside their individual router. So now let's add the routers import here. So I'll say from routers we want to import and let me spell that correctly. We want to import posts and we also want to import users. So just to show you in our sidebar how we've set this up. This is our package here. So we're saying from routers uh import post which is this post. py and import users which is this users py and now let me also make sure that we're still using everything else in our imports here and we are so we've removed everything uh that we can remove there a lot of those imports still stay because uh our template routes still use those now after the template setup here so after I have templates equal to this uh templates directory let's include the routers that we just created so to do this I can to say appinclude router and now we are going to say users router and now we're going to pass in that prefix and the prefix that we are going to use this is going to be for slapi slash users and we are also going to do something here that is called tags and a tags is going to be a list and we will pass in users here as a tag and now let me copy this and I'll do the same thing for post. So I'll say include post. outer. We want this prefix to be/appi/post. And for the tags we will do post as well. So let me explain what's happening here. So app. incclude router connects the router to our app. The prefix parameter adds that URL prefix to all routes in the router. So the router's empty string becomes basically the prefix and something like a forward slash user ID becomes forward slash API/ users slash user ID. So basically everything that we have here is getting appended to here in terms of the final URL. Now the tag parameter organizes the for/doccks page. It creates collapsible sections. So all of our user endpoints appear under a users header and all post endpoints are under a post header. Without tags, they'd just be in a flat list. So this helps nicely with organization as well. Now, one thing to watch out for is fast API uses function names as route names by default. So if you have a router function name with the same name as a template route, then it can conflict with URL 4. So for example, we have a function named home here. If I had in the router as well, then it might conflict with our template route named home. Here our solution that we have in place is just to use unique descriptive function names. And we already have that in place here. We're using nice descriptive function names for all of our routes. Uh but that's just something that you want to be on the lookout for. Don't name functions the same thing throughout different routers. So now let's verify our main. py structure here. So at this point it should contain imports for our routers. Here we have our lifespan function. We are creating our app. We have our static and media mounts here. We are setting up our templates. We're including our two routers. And then we have all of our template routes. These are basically our HTML view of our API. And we can see that this file is a lot less crowded now. And down here at the bottom, we still have our exception handlers as well. So all of those API routes are now gone from our main. py file. Now, one thing to point out here is that even though we changed a lot, all of the URLs are exactly the same and the responses are exactly the same. So, the functionality of our site is identical. We just moved where the routes are registered from the app object to the router object. It's purely

Segment 4 (15:00 - 20:00)

internal organization. So now, let's verify that by running our server here. So, I'll run the server. And now, let's go to our homepage here and reload this. We can see that still works. Let me try an API route here. The API routes still work. Now, if I go to the docs here and reload this. Now, this is one benefit that we got here because if we look at our documentation, our endpoints are now organized into groups. Here we have our users and these can be collapsed and we have our posts as well. That is what we get from the tags that we specified in those routes. So let's test that the functionality is all still working properly. So we have API users create user here. Let me go to try it out. I will create a test user and we will do test user atample. com. I will execute that and we can see that it created a user with a username or with a user ID of two here. So now let's collapse our users there and now let's create a post with that user. So I'll go to try it out and we will say testing routers router content and the user ID was two for that newly created user. I'll execute that and we can see that it created that uh post and we also get the author information in here. And let me make sure that looks good on the front end as well. And it does. So comparing to what we had before, we can see that our main. py, we're down to less than 150 lines of code here. And with our individual routes, these are about 150 themselves as well. So that's a lot better than having all of that shoved into just one file by itself. And this is a pattern that you're going to see in pretty much any production fast API application. So the benefits we get a separation of concerns obviously. So post logic lives in post user logic lives in users and app configuration and our front end live in main. py. Now I could even split off the front end if we wanted if the app grew even larger but I'm going to keep it in main. py for this series since it's not that much code. And this makes it a lot easier to find code as well. So, for example, if I'm looking for, you know, where is the create post endpoint? Well, instead of scrolling all the way through main. py and trying to find that, I know that that's going to be in post. py. And this also gives us a scalable structure as well. So, let's say that we wanted to add admin endpoints for administration duties. Well, we just create an admin. py uh file here within routers. and then each router would follow the same patterns that we've set up here. It's also better for teams so different developers can work on different routers and there would be fewer merge conflicts there. And there's also some testing benefits as well. So you can test routers individually and mock dependencies per route. Now there's different ways to organize routers. We organized by resource here which is common. So we have users py and post py. You could organize by version. So we could do v1 users py v2 users py. We could access by level. So we could do a public py versus admin. py or we could do it by feature like a billing. py if we had billing routes. But however you do it, the pattern is going to remain the same and it should help you organize your code. And that is what we're going to be using for the series going forward. Now, in the next video, we're going to add front-end forms with JavaScript. Now that our code is organized, we can build forms to create, edit, and delete post using the fetch API to interact with our clean API structure that we have here. And then we'll tackle authentication. So, only users can edit their own post on the front end and in the API. And our organized code that we've set up here will make adding those features a lot easier. But I think that's going to do it for this video. Hopefully now you have a good idea how to organize fast API applications using routers. This is a fundamental pattern that you'll use on any real world project. In the next video, we'll build front-end forms with JavaScript that talk to our API. But if anyone has any questions about what we covered in this video, then feel free to ask in the comments section below, and I'll do my best to answer those. And if you enjoy these tutorials and would like to support them, then there are several ways you can do that. The easiest way is to simply like the video and give it a thumbs up. Also, it's a huge help to share these videos with anyone who you think would find them useful. And if you have the means, you can contribute through Patreon or YouTube. And there are links to those pages in the description section below. Be sure to subscribe for future videos. And thank you all for watching.

Другие видео автора — Corey Schafer

Ctrl+V

Экстракт Знаний в Telegram

Экстракты и дистилляты из лучших YouTube-каналов — сразу после публикации.

Подписаться

Дайджест Экстрактов

Лучшие методички за неделю — каждый понедельник