W procesie tworzenia API kluczową rolę odgrywa odpowiednia dokumentacja, która umożliwia zarówno programistom, jak i użytkownikom API, prawidłowe korzystanie z udostępnionych zasobów. W przypadku platformy ASP.NET Core 9 dokumentacja ta staje się integralną częścią procesu tworzenia aplikacji webowych, umożliwiając łatwą integrację z systemami zewnętrznymi, a także gwarantując zgodność z zasadami REST.
W przykładzie, który omawiamy, mamy do czynienia z metodą HTTP POST, odpowiedzialną za rejestrację nowego produktu. Metoda ta może zwrócić dwa możliwe kody odpowiedzi HTTP: 400 (reprezentujący błąd związany z nieprawidłowym żądaniem) oraz 201, który wskazuje, że produkt został pomyślnie utworzony. Warto zauważyć, że kod 201 nie tylko potwierdza utworzenie zasobu, ale także w nagłówku odpowiedzi dodaje odnośnik umożliwiający dostęp do nowo utworzonego zasobu za pomocą metody GET. Zatem zwrócenie takiej odpowiedzi jest zgodne z najlepszymi praktykami, jakie zakłada protokół REST. Jednak, aby API było skuteczne i w pełni zrozumiałe dla konsumentów, niezbędne jest zapewnienie przejrzystości co do możliwych odpowiedzi i metod ich obsługi.
Aby poprawić dokumentację oraz zapewnić pełną zgodność z oczekiwaniami konsumentów API, warto zastosować atrybuty dostępne w ASP.NET Core 9, takie jak ProducesResponseType i Consumes. Pierwszy z nich pozwala określić typy kodów odpowiedzi HTTP, które będą zwracane przez metodę, a także precyzyjnie określić, jaki typ zawartości jest zwracany. Z kolei atrybut Consumes pozwala zdefiniować oczekiwany typ danych w treści żądania, który w tym przypadku jest wskazany jako JSON. Użycie tych atrybutów jest nie tylko rekomendowane, ale i niezbędne dla zapewnienia precyzyjnej dokumentacji i właściwego działania API.
Na przykładzie poniższego kodu widać, jak te atrybuty zostały zastosowane w metodzie POST, która rejestruje nowy produkt:
Po dodaniu odpowiednich atrybutów do metody, dokumentacja API zostaje automatycznie zaktualizowana w interfejsie Swagger, co pozwala na dokładne odwzorowanie odpowiedzi API, w tym różnych scenariuszy błędów i odpowiedzi na żądania.
Swagger UI stanowi nieocenione narzędzie, które umożliwia uruchomienie i testowanie zapytań API w czasie rzeczywistym. W przypadku przedstawionego przykładu, po dodaniu nowego produktu do ciała żądania w formacie JSON, użytkownik może kliknąć przycisk "Execute", aby wysłać zapytanie i zobaczyć odpowiedź API, która zawiera status 201 oraz dane nowo utworzonego produktu. Warto zaznaczyć, że w przypadku, gdyby API nie zwróciło żadnych informacji, może to prowadzić do niezgodności z oczekiwaniami konsumentów API, dlatego pełna dokumentacja zwróconych odpowiedzi jest kluczowa.
Warto również zwrócić uwagę na rolę komentarzy XML, które mogą zostać dodane do metod API. Komentarze te mogą być wykorzystane przez Swagger UI do generowania pełnej dokumentacji metod i parametrów żądań. Aby skorzystać z tej funkcji, konieczne jest skonfigurowanie projektu w taki sposób, aby dokumentacja XML była generowana podczas procesu kompilacji. Dzięki temu, dokumentacja jest zawsze aktualna i zawiera szczegółowe informacje na temat dostępnych metod, ich parametrów oraz możliwych odpowiedzi.
Prawidłowe przygotowanie dokumentacji API nie tylko ułatwia integrację systemów, ale także pozwala na efektywne zarządzanie usługami i szybkie wykrywanie potencjalnych problemów. ASP.NET Core 9 daje programistom potężne narzędzia do budowania zaawansowanych aplikacji API, których dokumentacja może być równie zaawansowana jak same aplikacje. Zastosowanie odpowiednich atrybutów, jak również korzystanie z narzędzi takich jak Swagger UI, pozwala na zbudowanie rozwiązania, które jest zarówno przejrzyste, jak i łatwe w integracji z innymi systemami.
Korzystając z ASP.NET Core, nie możemy zapominać o zapewnieniu odpowiedniej jakości dokumentacji API, która nie tylko zwiększa efektywność komunikacji z użytkownikami, ale także pomaga programistom w łatwiejszym zrozumieniu funkcjonalności poszczególnych metod oraz ewentualnych problemów, które mogą się pojawić w trakcie pracy z API.
Jak efektywnie pracować z EF Core i Dapper w aplikacjach ASP.NET Core 9?
W świecie nowoczesnego programowania aplikacji webowych, jedną z kluczowych kwestii jest efektywne zarządzanie danymi oraz interakcja z bazą danych. W kontekście aplikacji opartych na ASP.NET Core 9, dostępnych jest wiele narzędzi, które umożliwiają zarówno prostotę, jak i precyzyjną kontrolę nad tym procesem. W szczególności warto zwrócić uwagę na dwa podejścia do mapowania obiektowo-relacyjnego (ORM) – EF Core oraz Dapper. Choć oba narzędzia są potężnymi sojusznikami programisty, to każde z nich ma swoje specyficzne zastosowania w zależności od wymagań aplikacji.
W poniższym przykładzie mamy do czynienia z kodem, który ilustruje współpracę z bazą danych przy użyciu Dappera. Zaczynamy od prostego zapytania SQL, które pobiera dane klienta na podstawie jego identyfikatora. Kluczowym elementem w tym kodzie jest użycie parametru @Id, który pozwala na dynamiczną podmianę wartości w zapytaniu SQL. Dapper, będący mikro-ORM, zapewnia szybkie wykonanie zapytań, dzięki czemu jest szczególnie przydatny w kontekście operacji wymagających wysokiej wydajności, takich jak pobieranie dużych zbiorów danych.
Przyjrzyjmy się poszczególnym elementom kodu:
W C# i ASP.NET Core 9, konstrukcja => new to tzw. "discarded lambda", używana wtedy, gdy nie potrzebujemy korzystać z parametrów wyrażenia lambda. Obiekt SqlConnection jest dodawany do kontenera DI (Dependency Injection) przy użyciu tej samej ciągłej konfiguracji połączenia, jak w przypadku DbContext. Użycie metody AddScoped sprawia, że każde połączenie SQL jest współdzielone w ramach jednego żądania HTTP. Dzięki temu unikamy nadmiernego tworzenia nowych połączeń, co może prowadzić do problemów z wydajnością.
Metoda QueryFirstOrDefaultAsync jest używana do wykonania zapytania SQL, które zwraca pierwszy pasujący rekord lub null, jeśli taki rekord nie istnieje. Zaletą Dappera w tym przypadku jest automatyczne mapowanie danych na obiekt w C#, bez potrzeby ręcznego mapowania kolumn na właściwości klasy. Taka operacja odbywa się szybko i sprawnie, ponieważ Dapper jest zoptymalizowany pod kątem wydajności, w porównaniu do pełnych ORM-ów, takich jak Entity Framework Core.
Warto jednak pamiętać, że w przypadku dużych baz danych pobieranie wszystkich rekordów w jednym zapytaniu SQL może prowadzić do poważnych problemów z wydajnością, szczególnie gdy liczba danych wynosi miliony. Takie podejście jest wygodne do celów edukacyjnych lub testowych, ale w prawdziwej aplikacji należy unikać pobierania zbyt dużych zbiorów danych naraz. Zamiast tego należy zastosować paginację, czyli dzielenie wyników na mniejsze, łatwiejsze do obsługi fragmenty. Paginacja jest rozwiązaniem pozwalającym na efektywne przetwarzanie dużych zbiorów danych, nie obciążając nadmiernie pamięci i CPU serwera.
Kolejną istotną cechą Dappera jest jego zdolność do dynamicznego tworzenia zapytań SQL. Możemy na przykład użyć rozszerzenia Dapper SQL Builder, które pozwala na łatwe manipulowanie zapytaniami SQL w zależności od różnych warunków. Dapper SQL Builder jest przydatnym narzędziem w przypadku, gdy konieczne jest tworzenie zapytań, które zmieniają się w zależności od parametrów wejściowych.
Należy jednak pamiętać, że podczas korzystania z Dappera, szczególnie w bardziej zaawansowanych aplikacjach, wymaga to nieco większej odpowiedzialności ze strony programisty. W porównaniu do EF Core, Dapper nie zapewnia takich rozbudowanych mechanizmów, jak śledzenie zmian w obiektach czy automatyczne generowanie zapytań na podstawie modelu danych. Dlatego warto używać Dappera w kontekście zapytań, które są proste i wymagają pełnej kontroli nad generowanym SQL-em, natomiast w przypadkach, gdzie wymagane jest bardziej złożone mapowanie obiektów lub zarządzanie stanem obiektów, lepszym wyborem może być EF Core.
W kontekście wybierania między pełnym ORM, jakim jest EF Core, a mikro-ORM, takim jak Dapper, kluczową kwestią jest zrozumienie, w jakim kontekście i do jakiego typu aplikacji stosujemy konkretne narzędzie. EF Core jest wygodne, gdy zależy nam na prostocie i automatycznym mapowaniu obiektów, zwłaszcza gdy nasza aplikacja ma wiele operacji na danych, które mogą być łatwo wyrażone w formie LINQ. Z kolei Dapper zapewnia szybsze działanie i większą kontrolę nad zapytaniami SQL, ale wymaga od programisty większej znajomości samego języka SQL oraz bardziej zaawansowanej manipulacji danymi.
Podsumowując, oba narzędzia mają swoje zalety i ograniczenia. Wybór między nimi zależy od specyficznych potrzeb aplikacji, jej złożoności oraz wymagań wydajnościowych. Warto także pamiętać, że ASP.NET Core 9 daje nam elastyczność w łączeniu tych narzędzi, pozwalając na ich używanie w zależności od kontekstu operacji, co stanowi jedno z jego największych atutów.
Jak zorganizować i zabezpieczyć trasy API w aplikacji ASP.NET Core z użyciem tożsamości i autoryzacji ról?
W procesie tworzenia aplikacji opartych na ASP.NET Core, odpowiednia organizacja tras API oraz zabezpieczenie ich za pomocą tożsamości i mechanizmów autoryzacji odgrywają kluczową rolę w zapewnianiu skalowalności, łatwości w utrzymaniu oraz bezpieczeństwa aplikacji. W przykładzie, który omawiamy, trasy odpowiedzialne za przetwarzanie zapytań do API dotyczących kont i klientów zostały zarejestrowane przy użyciu metod rozszerzeń app.RegisterAccountRoutes i app.RegisterCustomerRoutes, co zapewnia lepszą separację odpowiedzialności i ułatwia zarządzanie kodem w pliku Program.cs.
Tworzenie metod rozszerzeń dla rejestracji tras, jak pokazano w przykładowym kodzie, jest dobrym podejściem, ponieważ pozwala na czyste i modularne zarządzanie trasami bez przeciążania głównego pliku konfiguracyjnego aplikacji. Metody rozszerzeń pozwalają na rozdzielenie logiki odpowiedzialnej za mapowanie tras, co poprawia czytelność i ułatwia zarządzanie kodem w większych aplikacjach.
Zdefiniowanie dwóch klas rozszerzeń, AccountRoutes i CustomerRoutes, w sposób pokazany w przykładzie, pozwala na organizowanie tras dla różnych typów zasobów API. Każda z tych klas posiada metodę Register{Entity}Routes, która mapuje odpowiednie trasy i przypisuje je do odpowiednich grup. Dla przykładu, trasa /accounts pozwala na pobieranie danych o kontach użytkowników, podczas gdy trasa /customers umożliwia uzyskanie informacji o klientach. Takie podejście pozwala na wygodne zarządzanie trasami i łatwe dodawanie nowych funkcji do aplikacji.
Z punktu widzenia praktyki dobrego programowania, tworzenie takich klas rozszerzeń pozwala na utrzymanie aplikacji w porządku, co w przyszłości będzie miało pozytywny wpływ na łatwość wprowadzania zmian i rozwoju projektu. Przykład implementacji metod rozszerzeń może wyglądać następująco:
Tego rodzaju podejście organizacyjne nie tylko poprawia czytelność kodu, ale także umożliwia łatwiejsze wprowadzanie zmian w przyszłości, ponieważ odpowiedzialność za poszczególne elementy API jest wyraźnie rozdzielona.
Również, w kontekście autoryzacji, ASP.NET Core 9 wprowadza możliwość implementacji autoryzacji opartej na rolach, co jest niezbędne w przypadku aplikacji wymagających różnorodnych poziomów dostępu. Dobrą praktyką w tym zakresie jest definiowanie polityk, które rozszerzają podstawową autoryzację opartą na rolach o bardziej złożoną logikę, umożliwiającą kontrolowanie dostępu do zasobów na podstawie różnych warunków, jak na przykład czas zatrudnienia użytkownika czy dodatkowe roszczenia.
Zdefiniowanie polityki w pliku Program.cs pozwala na centralne zarządzanie uprawnieniami w aplikacji. Polityki mogą być następnie przypisane do odpowiednich tras lub kontrolerów za pomocą atrybutu [Authorize]. Dla przykładu, możemy stworzyć politykę, która pozwala dostęp do niektórych zasobów tylko użytkownikom z rolą „Admin”:
Podobnie, dla bardziej złożonych scenariuszy, można zdefiniować politykę, która nie tylko sprawdza rolę użytkownika, ale również weryfikuje dodatkowe wymagania, takie jak długość zatrudnienia:
Takie podejście pozwala na precyzyjne dostosowanie poziomu dostępu użytkowników do zasobów aplikacji, co jest szczególnie ważne w dużych systemach, gdzie kontrolowanie dostępu ma kluczowe znaczenie dla bezpieczeństwa i integralności danych.
Następnie, po zaimplementowaniu autoryzacji, przychodzi czas na zabezpieczenie tras API. Jak pokazuje przykład z aplikacją bankową, po zaintegracji z tożsamością ASP.NET Core, domyślne trasy API mogą być dostępne bez autoryzacji. Aby wprowadzić autoryzację, konieczne jest dokonanie odpowiednich zmian w kodzie aplikacji, tak aby każda z tras wymagała uprzedniego uwierzytelnienia i autoryzacji użytkownika. Dzięki temu aplikacja nie będzie udostępniać swoich zasobów publicznie, co zabezpiecza dane przed nieuprawnionym dostępem.
Jak kolejność middleware wpływa na działanie aplikacji w ASP.NET Core 9?
Middleware w ASP.NET Core 9 stanowi podstawę przetwarzania żądań i odpowiedzi w aplikacji. Jednakże, to nie tylko obecność poszczególnych elementów middleware jest istotna, ale przede wszystkim ich kolejność umieszczenia w potoku aplikacji. To właśnie porządek, w jakim są one wywoływane, decyduje o poprawnym przebiegu logiki aplikacji i wpływa na jej funkcjonalność oraz stabilność.
Przykładowo, middleware odpowiedzialne za uwierzytelnianie (authentication) musi pojawić się przed middleware autoryzacji (authorization). W przeciwnym razie aplikacja nie będzie w stanie zweryfikować uprawnień użytkownika, skoro jeszcze nie została potwierdzona jego tożsamość. To fundamentalna zasada, która determinuje poprawne działanie mechanizmów bezpieczeństwa w aplikacjach ASP.NET Core 9.
Middleware to także koncepcja modularności — każdy element to niezależna jednostka funkcjonalna, którą można dodawać, usuwać lub modyfikować bez konieczności ingerencji w pozostałe części systemu. Ta modularność ułatwia tworzenie wielokrotnie wykorzystywalnych komponentów, które mogą być używane w różnych projektach lub różnych obszarach tego samego projektu. Kolejność łączenia middleware (tzw. kompozycja) pozwala natomiast dopasować przebieg przetwarzania żądań do specyficznych potrzeb aplikacji.
W praktyce, jeśli mamy middleware do logowania, uwierzytelniania oraz obsługi błędów, ich ustawienie w określonej kolejności zadecyduje o tym, czy błędy będą przechwytywane przed czy po autoryzacji, czy logi będą rejestrowane na początku czy na końcu obsługi żądania. To determinuje, jak zachowa się aplikacja w różnych scenariuszach i jaki wpływ na nią będą miały poszczególne komponenty.
Dzięki możliwości tworzenia własnych, niestandardowych middleware, można znacząco rozszerzyć funkcjonalność aplikacji. Przykładem jest middleware sprawdzające obecność i poprawność klucza API w nagłówkach żądania. Taka implementacja umożliwia globalne zarządzanie autoryzacją dostępu do API bez konieczności powielania tego sprawdzania w każdej akcji kontrolera.
Struktura middleware w ASP.NET Core opiera się na klasie zawierającej konstruktor przyjmujący delegat RequestDelegate oraz metodę Invoke lub InvokeAsync, która realizuje logikę przetwarzania. Delegat ten reprezentuje kolejne elementy potoku, co pozwala na wywołanie następnego middleware w sekwencji. Ta architektura umożliwia precyzyjną kontrolę nad przepływem żądań i odpowiedzi.
Middleware pozwala także na realizację zasady Separation of Concerns (SoC), czyli wyraźnego oddzielenia różnych obszarów odpowiedzialności w kodzie. Dzięki temu logika dotycząca autoryzacji, obsługi błędów, logowania czy modyfikacji żądań może być utrzymywana w odrębnych, czytelnych i łatwych do utrzymania komponentach.
Jednak korzyści płynące z middleware niosą ze sobą również wymagania dotyczące dobrych praktyk. Bardzo istotne jest, aby kolejność middleware była przemyślana i świadoma, gdyż niewłaściwe ułożenie może prowadzić do nieoczekiwanych błędów i trudnych do wykrycia problemów. Middleware powinno być proste i skupione na jednym zadaniu — skomplikowane, wielowątkowe operacje mogą niepotrzebnie obciążać potok i wpływać negatywnie na wydajność aplikacji.
Zarządzanie błędami powinno być spójne i jednolite w całej aplikacji, dlatego middleware odpowiedzialne za ich obsługę musi być konsekwentnie implementowane i umieszczone w odpowiednim miejscu potoku. Wysoka wydajność jest szczególnie istotna w aplikacjach o dużym obciążeniu, dlatego należy unikać kosztownych operacji w middleware przetwarzających każde żądanie.
Ponadto, warto korzystać z gotowych middleware dostarczanych przez framework, gdyż są one zoptymalizowane i dobrze przetestowane. Tworzenie niestandardowych komponentów powinno być motywowane konkretną potrzebą rozszerzenia funkcjonalności, której nie pokrywa istniejące rozwiązanie.
Znajomość mechanizmu middleware i umiejętność świadomego komponowania potoku przetwarzania żądań jest kluczowa dla budowania stabilnych, elastycznych i bezpiecznych aplikacji ASP.NET Core 9. Świadome zarządzanie middleware pozwala na efektywne wykorzystanie zasobów, łatwiejszą konserwację kodu i lepsze dostosowanie aplikacji do rosnących wymagań biznesowych i technicznych.
Jak zapewnić bezpieczeństwo aplikacji ASP.NET Core: Praktyczne podejście
Bezpieczeństwo aplikacji internetowych stało się jednym z kluczowych zagadnień współczesnego programowania. W szczególności w kontekście platformy ASP.NET Core, gdzie aplikacje są budowane na różnorodnych technologiach, zapewnienie odpowiedniej ochrony danych użytkowników i samej infrastruktury jest priorytetem. Poniżej przedstawiamy, jak skonfigurować systemy bezpieczeństwa w aplikacjach ASP.NET Core, biorąc pod uwagę zarówno bezpieczeństwo danych, jak i samej aplikacji.
ASP.NET Core oferuje wbudowane mechanizmy zarządzania tożsamościami użytkowników oraz kontrolowania dostępu, które mogą zostać skonfigurowane w celu zapewnienia odpowiednich poziomów ochrony. Kluczowym elementem jest integracja z ASP.NET Core Identity – systemem odpowiedzialnym za zarządzanie użytkownikami, rolami oraz ich autoryzacją w aplikacji. Identity pozwala na łatwe dodawanie i konfigurowanie użytkowników, nadawanie im ról, a także przypisywanie uprawnień do różnych zasobów w aplikacji.
Jednym z głównych składników systemu bezpieczeństwa jest token dostępu (access token), który służy do uwierzytelniania użytkowników oraz zapewnienia im dostępu do chronionych zasobów API. Wykorzystanie tokenów, takich jak JWT (JSON Web Token), umożliwia przechowywanie informacji o tożsamości użytkownika w sposób bezpieczny, bez konieczności przechowywania danych w sesji użytkownika. Tokeny są szczególnie przydatne w aplikacjach rozproszonych, gdzie komunikacja między serwisami odbywa się za pomocą API.
Bezpieczeństwo aplikacji internetowych nie kończy się na autoryzacji użytkowników. Istotne jest także zabezpieczenie danych przechowywanych w bazie danych, jak również samej aplikacji przed atakami z sieci. ASP.NET Core zapewnia narzędzia umożliwiające skuteczne zabezpieczenie danych, zarówno w trakcie ich transmisji (np. przez wykorzystanie HTTPS), jak i podczas przechowywania (np. przez szyfrowanie danych w bazie).
Kolejnym istotnym elementem, który powinien być uwzględniony w kontekście bezpieczeństwa, jest walidacja wejściowych danych. ASP.NET Core umożliwia skuteczne zabezpieczenie aplikacji przed atakami typu SQL Injection, Cross-Site Scripting (XSS), czy Cross-Site Request Forgery (CSRF). Dzięki odpowiedniej walidacji danych, zarówno po stronie serwera, jak i klienta, można uniknąć wielu potencjalnych zagrożeń.
Ponadto, w kontekście współczesnych praktyk DevOps i automatyzacji procesów dostarczania aplikacji, niezbędne jest wykorzystanie strategii Continuous Integration/Continuous Delivery (CI/CD). Dzięki tym praktykom możliwe jest szybkie wprowadzanie poprawek do aplikacji, a także bieżące testowanie jej pod kątem nowych zagrożeń. Odpowiednie monitorowanie aplikacji oraz wdrażanie mechanizmów takich jak automatyczne testy bezpieczeństwa, to kluczowe elementy w procesie utrzymania aplikacji w stanie wolnym od podatności.
Bezpieczeństwo w aplikacjach ASP.NET Core powinno być także realizowane przez wdrożenie odpowiednich procedur kontroli dostępu. Istotnym aspektem jest segregacja obowiązków i przypisanie odpowiednich ról użytkownikom. System ról w ASP.NET Core pozwala na przydzielanie uprawnień na poziomie aplikacji, co umożliwia skuteczną kontrolę nad dostępem do poszczególnych zasobów. Z kolei, polityki bezpieczeństwa (np. w postaci wymagania silnych haseł czy autentykacji wieloskładnikowej) pozwalają na dalsze wzmocnienie poziomu zabezpieczeń aplikacji.
Dodatkowo, w procesie zabezpieczania aplikacji, niezbędne jest stosowanie wzorców projektowych takich jak wzorzec „Factory”, który pozwala na zarządzanie konfiguracją aplikacji w sposób bardziej elastyczny. Dzięki temu możliwe jest dynamiczne dostosowanie aplikacji do zmieniających się warunków operacyjnych bez konieczności jej przebudowy.
Ważnym zagadnieniem w kontekście bezpieczeństwa jest także implementacja middleware, które pełni funkcję „pośrednika” w trakcie przetwarzania żądań HTTP. Middleware w ASP.NET Core umożliwia stosowanie szeregu dodatkowych środków ochrony, takich jak sprawdzanie integralności żądań, walidacja nagłówków, a także szyfrowanie danych.
Podstawowym celem, na którym powinna koncentrować się każda aplikacja, jest zapewnienie użytkownikowi bezpieczeństwa i prywatności jego danych. Dzięki odpowiednim praktykom programistycznym oraz konfiguracji systemu, aplikacja ASP.NET Core może stać się solidnym fundamentem bezpiecznego rozwiązania.
Nie można zapominać o bieżącym monitorowaniu oraz audytowaniu aplikacji po jej wdrożeniu. Stosowanie systemów monitoringu, takich jak Azure Monitor czy Datadog, pozwala na wczesne wykrywanie ewentualnych zagrożeń oraz szybkie reagowanie na nie, minimalizując ryzyko poważniejszych incydentów bezpieczeństwa.
Jak skonfigurować menu stopki w Publii CMS i dodać informacje do stopki
Jak efektywnie używać narzędzi profilowania wydajności w Visual Studio?
Jakie równania rządzą zachowaniem układu w rozszerzonej termodynamice? Przykład gazów i helu II.

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский