- Wybierz pomiędzy układami opartymi na typie pliku lub funkcjach, na podstawie rozmiaru projektu, architektury i potrzeb zespołu, stawiając spójność jako najwyższy priorytet.
- Skorzystaj ze wskazówek dotyczących typów FastAPI, modeli Pydantic i wstrzykiwania zależności, aby zachować prostotę routingu, modułowość logiki i wydajność walidacji, a także możliwość wielokrotnego użytku.
- Ustrukturyzuj bezpieczeństwo, testowanie, asynchroniczne wejście/wyjście i konfigurację jako kwestie najwyższej wagi, aby skalowanie do produkcji i wielu zespołów nie wymagało całkowitego przepisania.
- Wprowadź jasne konwencje nazewnictwa, migracji i narzędzi, aby zachować możliwość utrzymania rosnącej floty monolitów FastAPI lub mikrousług w miarę upływu czasu.
Zaprojektowanie czystej, skalowalnej struktury dla projektu FastAPI to jedna z tych decyzji, które na początku wydają się drobne, ale po sześciu miesiącach całkowicie zmieniają Twoje życieKiedy baza kodu się rozrosła, zespół się rozrósł i próbujesz wyśledzić błąd w wielu modułach. Dobry układ przyspiesza onboarding, zmniejsza regresje i sprawia, że refaktoryzacja jest znacznie mniej bolesna.
FastAPI zapewnia ogromną elastyczność, ale oznacza to również konieczność aktywnego wyboru i egzekwowania konwencjiW tym przewodniku zbierzemy najprzydatniejsze pomysły zaczerpnięte z rzeczywistych projektów FastAPI w środowisku produkcyjnym oraz znanych repozytoriów najlepszych praktyk, porównamy główne układy projektów i przyjrzymy się, jak współdziałają one z podstawowymi koncepcjami FastAPI, takimi jak wstrzykiwanie zależności, walidacja, asynchroniczne wejście/wyjście, testowanie i wdrażanie.
Dlaczego struktura projektu ma tak duże znaczenie w FastAPI
Solidna struktura to podstawa, która sprawia, że aplikacja FastAPI jest zrozumiała, mimo że rośnie pod względem rozmiaru i złożonościBez niej nawet framework o świetnej ergonomii szybko zmienia się w stertę doraźnych modułów, cyklicznych importów i powielonej logiki.
Z punktu widzenia inżynierii struktura ma bezpośredni wpływ na skalowalność:gdy moduły są rozdzielone i jasno określone są obowiązki, można dzielić usługi, wprowadzać kolejki lub skalować różne części systemu niezależnie, bez konieczności przepisywania wszystkiego.
Kolejnym dużym osiągnięciem jest łatwość utrzymaniaGdy każda trasa, schemat i model bazy danych ma przewidywalny adres, programiści tracą mniej czasu na przeszukiwanie plików, a więcej na rozwiązywanie rzeczywistych problemów biznesowych. Łatwiej jest również przeprowadzać przeglądy kodu, ponieważ wszyscy korzystają z tego samego modelu mentalnego.
W projektach zespołowych spójny układ znacząco poprawia współpracęNowi pracownicy potrafią wywnioskować, gdzie wprowadzić nowe funkcje, zespół ds. zapewnienia jakości może znaleźć właściwe punkty wejścia do przetestowania, a zespół DevOps potrafi zrozumieć, które elementy są kluczowe dla uruchomienia aplikacji (na przykład, gdzie znajduje się obiekt aplikacji ASGI i jak podłączona jest baza danych).

Podstawowe zasady strukturyzowania projektów FastAPI
Przed wyborem układu folderów warto ustalić kilka zasad, którymi należy się kierować przy podejmowaniu decyzji dotyczących architekturyTego typu pomysły pojawiają się wielokrotnie w udanych bazach kodu FastAPI.
Rozdzielenie obaw Pierwszy filar to: utrzymywanie routingu, trwałości, reguł biznesowych i kodu integracyjnego w różnych miejscach. Punkty końcowe powinny koordynować przypadki użycia, a nie osadzać zapytań SQL, manipulacji JSON i wywołań usług zewnętrznych w jednej długiej funkcji.
Modułowość jest drugim filaremZamiast jednego gigantycznego, monolitycznego pakietu, dąż do mniejszych, skoncentrowanych modułów lub podpakietów, które hermetyzują powiązane zachowania. To znacznie ułatwia ponowne wykorzystanie fragmentów, testowanie ich w izolacji i ewentualne rozdzielenie na mikrousługi, jeśli zajdzie taka potrzeba.
Wstrzykiwanie zależności to klej łączący te moduły bez ścisłego powiązaniaSystem zależności FastAPI umożliwia deklarowanie potrzeb trasy lub usługi (sesji bazy danych, konfiguracji, uwierzytelnionego użytkownika itp.) i umożliwienie platformie ich zapewnienia, co jest idealnym rozwiązaniem pod kątem testowania i ponownego wykorzystania.
Sama testowalność musi być traktowana jako wymaganie pierwszorzędneJeśli struktura utrudnia uruchomienie aplikacji w pamięci, obejście zależności i dotarcie do punktów końcowych za pomocą klienta testowego, albo pominiesz testy, albo będziesz walczyć z własną architekturą. Dobra struktura sprawia, że efekty uboczne są lokalne, a ścieżki importowalne z testów.
Dwa dominujące układy projektów FastAPI: według typu pliku i według funkcji
W ekosystemie FastAPI zazwyczaj znajdziesz dwie wyraźne rodziny układów: projekty uporządkowane według typu pliku (routery, modele, schematy, CRUD) oraz projekty uporządkowane według domeny lub funkcji (uwierzytelnianie, użytkownicy, wpisy, płatności itp.). Każdy z nich wyróżnia się w innym kontekście.
Struktura oparta na typie pliku (routery, schematy, modele, CRUD)
Podejście oparte na typie pliku odzwierciedla sposób, w jaki wiele oficjalnych przykładów i samouczków wprowadza FastAPIGrupujesz kod według jego roli technicznej: warstwa routingu, schematy pydantyczne, modele baz danych, operacje CRUD, narzędzia itd.
Minimalistyczny, ale realistyczny układ może wyglądać tak (skrócona wersja dla większej przejrzystości):
Przykładowy układ: .├── app
│ ├── __init__.py
│ ├── main.py # FastAPI app initialization
│ ├── dependencies.py # shared dependencies
│ ├── routers
│ │ ├── __init__.py
│ │ ├── items.py # endpoints for items
│ │ └── users.py # endpoints for users
│ ├── crud
│ │ ├── item.py # item CRUD
│ │ └── user.py # user CRUD
│ ├── schemas
│ │ ├── item.py # pydantic models for items
│ │ └── user.py # pydantic models for users
│ ├── models
│ │ ├── item.py # ORM models for items
│ │ └── user.py # ORM models for users
│ ├── external_services
│ │ ├── email.py # email provider client
│ │ └── notification.py # push / notification client
│ └── utils
│ ├── authentication.py
│ └── validation.py
├── tests
│ ├── test_main.py
│ ├── test_items.py
│ └── test_users.py
├── requirements.txt
└── README.md
W tym stylu każdy katalog najwyższego poziomu pod app/ ma jedną odpowiedzialność, Na przykład, routers/ opisuje punkty wejścia HTTP, schemas/ deklaruje kształty wejściowe/wyjściowe i models/ reprezentują tabele bazy danych.
Ten układ sprawdza się znakomicie w przypadku małych i średnich usług lub mikrousługDomena jest zazwyczaj na tyle wąska, że podział według roli technicznej nie powoduje tarcia. Większość punktów końcowych korzysta z tego samego, ograniczonego zestawu modeli, a kodem zajmuje się jednocześnie tylko kilka zespołów.
Do głównych zalet struktury plików należy bardzo niskie obciążenie poznawcze dla początkujących oraz drzewo katalogów ściśle zgodne z dokumentacją FastAPI. Dla kogoś uczącego się frameworka, zobaczenie dedykowanego routers/ folder i schemas/ folder często wydaje się bardziej intuicyjny niż przeskakiwanie bezpośrednio do pakowania sterowanego domeną.
Struktura zorientowana na funkcje lub moduły src/
W miarę jak projekty stają się monolitami obejmującymi wiele domen, układ typów plików zaczyna skrzypieć. Otrzymujesz ogromne katalogi takie jak routers/ z dziesiątkami plików, złożonymi importami międzymodułowymi i logiką biznesową rozproszoną po niezwiązanych ze sobą pakietach.
Alternatywą, która lepiej się skaluje, jest struktura oparta na funkcjach lub domenachTutaj umieszczasz cały kod dla konkretnej domeny w jednym podpakiecie: trasy, schematy, modele, usługi, konfigurację i wyjątki specyficzne dla modułu.
Przykładowy układ inspirowany popularnymi repozytoriami najlepszych praktyk wygląda następująco:
Przykładowe drzewo plików: fastapi-project
├── alembic/
├── src
│ ├── auth
│ │ ├── router.py # auth endpoints
│ │ ├── schemas.py # pydantic models
│ │ ├── models.py # DB models
│ │ ├── dependencies.py # auth-specific dependencies
│ │ ├── config.py # local configs
│ │ ├── constants.py # auth error codes / constants
│ │ ├── exceptions.py # auth-specific exceptions
│ │ ├── service.py # business logic
│ │ └── utils.py # helpers
│ ├── aws
│ │ ├── client.py
│ │ ├── schemas.py
│ │ ├── config.py
│ │ ├── constants.py
│ │ ├── exceptions.py
│ │ └── utils.py
│ ├── posts
│ │ ├── router.py
│ │ ├── schemas.py
│ │ ├── models.py
│ │ ├── dependencies.py
│ │ ├── constants.py
│ │ ├── exceptions.py
│ │ ├── service.py
│ │ └── utils.py
│ ├── config.py # global configs
│ ├── models.py # shared DB models
│ ├── exceptions.py # shared exceptions
│ ├── pagination.py # reusable pagination logic
│ ├── database.py # DB connection & session management
│ └── main.py # FastAPI app factory / entry point
├── tests
│ ├── auth
│ ├── aws
│ └── posts
├── templates
│ └── index.html
├── requirements
│ ├── base.txt
│ ├── dev.txt
│ └── prod.txt
├── .env
├── logging.ini
└── alembic.ini
Na tym świecie, src/ jest szczytem wewnętrznego drzewa aplikacjiKażda domena, taka jak auth or posts, staje się niemalże miniusługą: zawiera własny router, schematy, modele, stałe, typy błędów i warstwę usług biznesowych.
Główną zaletą jest lokalność zmian:kiedy dodajesz nową funkcję do posts, rzadko musisz dotykać jakiegokolwiek niepowiązanego pakietu. Testy mogą również istnieć obok swoich funkcji (na przykład pod tests/posts/), co zachęca do większego zasięgu.
Ta struktura jest szczególnie odpowiednia dla aplikacji monolitycznych z wieloma domenami i zespołami, gdzie chcesz wspierać pracę równoległą i redukować konflikty scalania. Dobrze współpracuje również z koncepcjami projektowania zorientowanego na domenę, takimi jak ograniczone konteksty i agregaty.

Wybór właściwego układu dla projektu FastAPI
Wybór pomiędzy typem pliku a strukturą opartą na funkcjach nie jest kwestią słuszności lub niesłuszności, ale dopasowania architektury do oczekiwań dotyczących rozwojuNiewielkie narzędzie wewnętrzne z zaledwie kilkoma punktami końcowymi nie odniesie większych korzyści ze skomplikowanego układu domeny.
W przypadku mikrousług i interfejsów API o wąskim zakresie układ typów plików jest zwykle prostszyKażda usługa często koncentruje się na jednym zadaniu (API rozliczeniowe, nadawca powiadomień, mikrousługa raportowania), a programiści intuicyjnie wiedzą już, gdzie umieścić nowe trasy lub schematy.
W przypadku większych monolitów podział według domeny prawie zawsze jest w dłuższej perspektywie korzystny. Kiedy masz moduły do profili, subskrypcji, treści, płatności, analiz i innych, umieszczanie każdego routera w jednym katalogu staje się chaotyczne. Grupowanie według funkcji sprawia, że każdy segment systemu pozostaje niezależny.
Weź również pod uwagę strukturę swojego zespołuJeśli jeden mały zespół posiada całą bazę kodu, spójność może być łatwiejsza do utrzymania dzięki prostemu układowi. Jeśli wiele zespołów współdzieli monolit i każdy z nich posiada obszar domeny, struktura oparta na funkcjach pozwala im poruszać się szybciej, nie wchodząc sobie nawzajem w drogę.
Niezależnie od tego, co wybierzesz, ważniejsza jest spójność niż dokładny kształt drzewaZmiana układu w trakcie projektu jest bolesna, dlatego warto poświęcić trochę czasu na przemyślenie projektu i spisanie krótkiego wewnętrznego przewodnika po stylu, co później się opłaci.
Zrozumienie samego FastAPI: co strukturujesz
Aby zaprojektować sensowną strukturę, potrzebny jest jasny model mentalny tego, co FastAPI faktycznie dla Ciebie robiW swojej istocie FastAPI to framework internetowy ASGI, którego celem jest tworzenie interfejsów API HTTP w Pythonie 3.7+ przy użyciu wskazówek dotyczących typów.
FastAPI w dużym stopniu opiera się na Pydantic w zakresie walidacji danych i serializacjiOferuje znacznie więcej niż proste pola „wymagane vs. opcjonalne”; możesz wyrażać rozbudowane ograniczenia i transformacje bezpośrednio w swoich modelach.
Ponieważ schemat OpenAPI jest generowany bezpośrednio z punktów końcowych i modeli, FastAPI generuje również interaktywną dokumentację. Po wyjęciu z pudełka otrzymasz interfejs użytkownika Swagger /docs i ReDoc w /redoc, które są nieocenione podczas współpracy z programistami front-end lub zewnętrznymi integratorami.
Pod maską FastAPI działa na serwerach ASGI, takich jak UvicornDzięki temu Twoja aplikacja może sprawnie obsługiwać wiele równoczesnych połączeń i korzystać z takich funkcji jak długotrwałe połączenia WebSocket bez zbędnych ceregieli.
FastAPI jest również wyraźny w kwestii żądań i odpowiedziKażdy punkt końcowy to po prostu zwykła funkcja Pythona (synchroniczna lub asynchroniczna) ozdobiona @app.get, @app.post i przyjaciele, odbierający dane dotyczące ścieżki/zapytania/treści i zwracający odpowiedź, zazwyczaj słownik lub model Pydantic.
Asynchroniczność kontra synchronizacja: jak wydajność wpływa na strukturę
FastAPI został zaprojektowany przede wszystkim jako framework asynchroniczny, ale obsługuje zarówno punkty końcowe asynchroniczne, jak i synchronizowaneZrozumienie ich wewnętrznego zachowania pozwoli Ci zaprojektować usługi, wybrać klientów i uporządkować moduły obsługujące wejście/wyjście.
Kiedy deklarujesz async def trasa, FastAPI uruchamia ją bezpośrednio w pętli zdarzeńStruktura zakłada, że wszelkie długotrwałe operacje wewnątrz będą nieblokującymi obiektami oczekującymi, takimi jak asynchroniczny sterownik bazy danych lub klient HTTP zbudowany na asyncio.
Jeżeli przypadkowo nawiążesz połączenie blokujące (np. time.sleep()pętle obciążające procesor lub wolne biblioteki, które wykonują operacje wejścia/wyjścia sieciowego synchronicznie) wewnątrz tych asynchronicznych tras, skutecznie zamrozisz pętlę zdarzeńDopóki ta operacja się nie zakończy, nie zostaną przetworzone żadne inne żądania, co jest sprzeczne z celem asynchroniczności.
Trasy synchronizacji zachowują się inaczej: FastAPI wykonuje je w puli wątkówBlokowanie pracy na tych trasach obejmuje tylko wątek roboczy, a nie całą pętlę zdarzeń, dzięki czemu serwer nadal może akceptować nowe żądania. W ten sposób FastAPI zachowuje elastyczność, gdy trzeba polegać na bibliotekach synchronicznych.
Te same zasady dotyczą zależnościObsługiwane są zależności zarówno synchronizowane, jak i asynchroniczne, ale zależności synchronizowane są również uruchamiane w puli wątków. W przypadku niewielkich funkcji pomocniczych niezwiązanych z wejściem/wyjściem często lepiej jest oznaczyć je jako asynchroniczne, aby uniknąć narzutu i ograniczeń wątków, gdy jest to niepotrzebne.
Obciążenia obciążające procesor to osobna historiaNiezależnie od tego, czy uruchamiasz je synchronicznie, czy asynchronicznie w ramach procesu, GIL (Global Interpreter Lock) oznacza, że tylko jeden wątek wykonuje bajtkod Pythona na raz. W przypadku zadań takich jak przetwarzanie dużych ilości danych, transkodowanie obrazów lub wnioskowanie ML, rozważ odciążenie zadań w oddzielnych procesach lub kolejkach zewnętrznych.
Walidacja i kształtowanie danych za pomocą Pydantic
Pydantic to silnik stojący za funkcjami walidacji i serializacji FastAPIOferuje znacznie więcej niż proste pola „wymagane vs. opcjonalne”; możesz wyrażać rozbudowane ograniczenia i transformacje bezpośrednio w swoich modelach.
Typowe przypadki użycia obejmują weryfikację długości ciągu, zakresów liczbowych, formatów wiadomości e-mail lub złożonych struktur zagnieżdżonychModele mogą również opierać się na wyliczeniach, wyrażeniach regularnych, niestandardowych walidatorach i wielu innych narzędziach do oczyszczania danych wejściowych przed ich wykorzystaniem w logice biznesowej.
Potężnym wzorcem jest zdefiniowanie niestandardowego modelu bazowego dla Twojego projektuDziedzicząc wszystkie schematy z jednej klasy bazowej, można ujednolicić zachowania przekrojowe, takie jak format serializacji daty i godziny, metody narzędziowe zwracające wyłącznie wartości bezpieczne w formacie JSON lub wspólne flagi konfiguracji.
Pydantic świetnie nadaje się do czystej walidacji danych, ale nie wie nic o Twojej bazie danych ani usługach zewnętrznychJeśli reguły zależą od zapytania (np. od sprawdzenia, czy identyfikator użytkownika istnieje lub czy adres e-mail jest unikalny), powszechną, dobrą praktyką jest przeniesienie tych walidacji do zależności, a nie do walidatorów modelu Pydantic.
W ten sposób zachowujesz deklaratywny charakter schematów i ponownie wykorzystujesz walidacje w wielu punktach końcowychZależność może pobrać jednostkę, wymusić reguły dostępu i wstrzyknąć wynik do trasy, podczas gdy FastAPI buforuje swój wynik dla każdego żądania, aby uniknąć duplikowania pracy, gdy ta sama zależność jest używana wielokrotnie.
Zależności jako element składowy czystej architektury
System wstrzykiwania zależności FastAPI to nie tylko składnia dla parametrów, to podstawowe narzędzie architektonicznePrawidłowe użycie zależności pozwala na współdzielenie logiki, egzekwowanie niezmienników i utrzymywanie ścieżek bardzo małych i ekspresyjnych.
Do typowych przykładów należą dostawcy sesji baz danych, ładowarki konfiguracji, pomocnicy uwierzytelniania i analizatory stronicowaniaZamiast ręcznie otwierać i zamykać sesje lub powtarzać parametry paginacji wszędzie, deklarujesz je raz jako zależności i ponownie ich używasz.
Subtelna, ale ważna wskazówka projektowa: rozbicie zależności na małe, możliwe do złożenia jednostkiZamiast jednego giganta get_current_user_with_all_checks funkcji możesz mieć oddzielne zależności do analizy JWT, ładowania użytkownika, weryfikacji aktywności konta i sprawdzania, czy użytkownik jest właścicielem danego zasobu.
Ponieważ FastAPI buforuje wyniki zależności w ramach jednego żądania, ich składanie jest tanieJeśli trzy różne zależności ponownie wykorzystują pomocnika niższego poziomu (na przykład do analizy oświadczeń JWT), pomocnik ten zostanie uruchomiony tylko raz na żądanie, nawet jeśli będzie odwoływany wielokrotnie.
Podczas projektowania tras nazewnictwo ścieżek może ułatwiać lub utrudniać ponowne wykorzystanie zależnościNa przykład, jeśli kilka punktów końcowych zweryfikuje, że profile_id istnieje, używanie tej samej nazwy w parametrach ścieżki w sposób spójny ułatwia podłączenie pojedynczej zależności, która opiera się na profile_idzamiast wymyślać wiele wariantów, takich jak creator_id które mają to samo znaczenie.
Bezpieczeństwo, uwierzytelnianie i autoryzacja w Twojej strukturze
Bezpieczeństwo to jedna z dziedzin, w której przejrzysta struktura szybko się opłacaMieszanie logiki uwierzytelniania bezpośrednio z losowymi trasami utrudnia audyt reguł dostępu i ułatwia przypadkowe ujawnienie danych.
W układach opartych na funkcjach powszechnym wzorcem jest posiadanie auth pakiet z własnym routerem, schematami, warstwą usług i wyjątkamiTen moduł będzie obsługiwał rejestrację użytkowników, przepływy logowania, wydawanie tokenów i weryfikację oraz może definiować zależności takie jak get_current_user które importują inne moduły.
W ramach tego pakietu uwierzytelniania możesz obsługiwać wiele mechanizmów uwierzytelniania, takie jak OAuth2 z hasłem i tokenami nośnika, klucze API do połączeń między usługami lub tokeny oparte na JWT do interfejsów API bezstanowych. fastapi.security Narzędzia te pomagają również w opisaniu tych przepływów w OpenAPI.
Ważne jest, aby oddzielić uwierzytelnianie (kim jest użytkownik) od autoryzacji (co ma prawo zrobić). Twoja struktura powinna jasno określać, gdzie na bieżąco przeprowadzane są kontrole uprawnień: na przykład w dedykowanej warstwie usług lub zasad, a nie w rozproszonych, doraźnych if oświadczenia na każdej trasie.
Zawsze, gdy masz do czynienia z hasłami, postępuj zgodnie z ustalonymi praktykami kryptograficznymiTajemnice haszujące należy haszować za pomocą powolnego algorytmu z solą, takiego jak bcrypt lub argon2, korzystając z renomowanych bibliotek, unikać ręcznego szyfrowania i traktować przechowywanie tokenów, ochronę CSRF i bezpieczeństwo transportu (HTTPS) jako pierwszorzędne elementy projektu.
Efektywne testowanie aplikacji FastAPI
Struktura i testowanie wzajemnie się wzmacniają: przejrzysty układ naturalnie prowadzi do bardziej testowalnego koduDzięki FastAPI możesz testować na kilku poziomach, od czystych testów jednostkowych usług po pełne testy integracyjne obejmujące warstwę HTTP.
Testy jednostkowe powinny koncentrować się na małych fragmentach niepowodujących efektów ubocznych: funkcje czyste, walidatory Pydantic, usługi biznesowe działające na danych w pamięci. Zazwyczaj są one bardzo szybkie i stanowią pierwszą linię obrony przed regresjami.
Do ćwiczenia rzeczywistych punktów końcowych HTTP można użyć wbudowanego klienta testowego opartego na Starlette lub nowoczesnych klientach asynchronicznych, takich jak httpxPomysł polega na zaimportowaniu aplikacji, zastąpieniu zależności w razie potrzeby (na przykład wstrzykując testową sesję bazy danych) i wysyłaniu żądań bez uruchamiania zewnętrznego serwera.
Jeśli pracujesz ze sterownikami baz danych asynchronicznych lub innymi integracjami asynchronicznymi, warto od początku skonfigurować klienta testowego asynchronicznegoMieszanie stylów testów synchronicznych i asynchronicznych na późniejszym etapie często prowadzi do mylących problemów z pętlami zdarzeń, które są trudniejsze do debugowania niż po prostu standaryzacja jednego podejścia.
Wykorzystanie bazy danych w testach oddziałuje również na Twoją strukturę. Posiadając centralną database.py moduł definiujący fabryki silników i sesji, ułatwia tworzenie baz danych testowych, opakowywanie testów w transakcje lub korzystanie z mechanizmów, które obcinają tabele pomiędzy uruchomieniami.
Od rozwoju lokalnego do wdrożenia produkcyjnego
Aplikacje FastAPI są łatwe do uruchomienia lokalnie, ale wymagają nieco więcej planowania w środowisku produkcyjnymStruktura projektu powinna jasno określać sposób tworzenia aplikacji, źródło konfiguracji oraz sposób podłączenia rejestrowania i kontroli stanu.
Do celów programistycznych większość zespołów korzysta z Uvicorn z funkcją automatycznego przeładowywania, zwykle za pomocą polecenia takiego jak uvicorn app.main:app --reload lub w nowszych konfiguracjach, fastapi dev. Zapewnia to szybkie pętle sprzężenia zwrotnego i doskonale sprawdza się podczas iteracji.
Podczas produkcji zazwyczaj potrzebna jest bardziej solidna konfiguracja: Roboty Uvicorn lub Hypercorn zarządzane przez nadzorcę procesów lub wrapper WSGI/ASGI, taki jak Gunicorn, często za odwrotnym serwerem proxy (NGINX lub zarządzanym modułem równoważenia obciążenia). Celem jest kontrolowanie liczby robotów, przekroczeń limitu czasu i płynnych restartów, na podstawie… nowoczesne praktyki DevOps.
Konfiguracja powinna być sterowana zmiennymi środowiskowymi, a nie wartościami zakodowanymi na stałeNarzędzia do zarządzania ustawieniami Pydantic i podobne mogą pomóc Ci deklarować klasy ustawień typowych i ładować je podczas uruchamiania, centralizując wszystkie ustawienia specyficzne dla środowiska w jednym miejscu.
Zanim nazwiesz swoją aplikację gotową do produkcji, sprawdź kilka podstawowych kwestii:ustrukturyzowane rejestrowanie, podstawowe metryki, punkty końcowe dotyczące stanu zdrowia dla sond żywotności i gotowości, rozsądne limity rozmiaru ciała oraz jasna polityka dotycząca udostępniania dokumentacji wyłącznie w środowiskach niepublicznych, jeśli interfejs API nie jest przeznaczony do użytku ogólnego.
Nazewnictwo, projektowanie baz danych i migracje
Sposób nazywania elementów w modelach i plikach schematów również stanowi część struktury projektuNiespójne nazewnictwo to jeden z najszybszych sposobów na wprowadzenie w błąd programistów pracujących nad bazą kodu, której nie stworzyli.
Prostą i skuteczną konwencją jest użycie lower_case_snake nazwy tabel i kolumn, preferuj pojedyncze nazwy tabel (na przykład post, post_like, user_playlist) i grupuj powiązane tabele za pomocą wspólnego prefiksu, takiego jak payment_ or post_.
W przypadku pól czasowych sufiksy takie jak _at dla dat i godzin oraz _date w przypadku prostych dat zachowaj przejrzystość. Podejście ścisłe w tym przypadku zapobiega zgadywaniu „czy to znacznik czasu, czy data?” podczas odczytywania schematów lub surowych zapytań.
Migracje zasługują na szczególną opiekę; powinny być deterministyczne, odwracalne i opisowe — rozważ następujące praktyki migracji baz danychWiele zespołów przyjmuje wzorzec nazw plików migracji, taki jak YYYY-MM-DD_slug.py, co ułatwia śledzenie historii i zrozumienie zmian bez konieczności czytania całego pliku diff.
W przypadku złożonych raportów lub zagnieżdżonych odpowiedzi wykorzystaj swoją bazę danych zamiast nadmiernie przetwarzać dane w PythonieNowoczesne silniki SQL potrafią wykonywać łączenia, agregacje i budowanie JSON-a znacznie szybciej niż CPython, a zwracanie gotowych struktur do FastAPI często upraszcza modele odpowiedzi.
Narzędzia, formatowanie i konwencje zespołowe
Dobrze ustrukturyzowany projekt łatwiej utrzymać w czystości, gdy korzysta się z narzędzi do egzekwowania reguł styluFormatery kodu, lintery i haki pre-commit pozwalają skupić się na logice biznesowej, zamiast kłócić się o odstępy podczas przeglądów kodu.
Ostatnio narzędzia takie jak Ruff zyskały na popularności, ponieważ łączą wiele ról w jednymZamiast żonglować oddzielnymi narzędziami do formatowania, sortowania importów i lintingu, możesz uruchomić jedno szybkie narzędzie, które będzie egzekwować setki reguł w całej bazie kodu.
Uruchamianie tych narzędzi za pomocą prostego skryptu lub haków przed zatwierdzeniem pozwala utrzymać barierę na niskim poziomieNie każdy zespół potrzebuje skomplikowanego zestawu haczyków, ale posiadanie przynajmniej jednego polecenia standaryzującego układ kodu to łatwy cel.
Na koniec rozważ udokumentowanie swoich wewnętrznych konwencji w krótkim „podręczniku inżynierskim” to odniesienia zwinne metody tworzenia oprogramowaniaOpisz, jak należy nazywać moduły, kiedy utworzyć nowy pakiet domeny, jak strukturować testy i jakie wzorce bezpieczeństwa są obowiązkowe. Dzięki temu wiedza nie będzie zakorzeniona wyłącznie w głowach doświadczonych programistów.
Projektowanie struktury projektu FastAPI ma na celu uczynienie przyszłej pracy przewidywalną i nudną:gdy każdy nowy punkt końcowy, model lub usługa ma oczywiste miejsce, programiści mogą działać szybko i bez niespodzianek, bezpieczeństwo jest łatwiejsze do zweryfikowania, a aplikacja ma znacznie większą szansę na przetrwanie rzeczywistego rozwoju bez załamania się pod własnym ciężarem.