Javalin - Zadania dla studentów
Instrukcje ogólne
Poniżej znajduje się zestaw zadań do samodzielnego wykonania. Zadania są podzielone na trzy poziomy trudności:
- Poziom 1 (Łatwy) - podstawowa wiedza o Javalin
- Poziom 2 (Średni) - połączenie kilku konceptów
- Poziom 3 (Trudny) - zaawansowane funkcjonalności
Dla każdego zadania:
- Przeczytaj opis
- Zdefiniuj wymagania
- Zaimplementuj rozwiązanie
- Przetestuj w Postmanie lub przeglądarce
Poziom 1 - Zadania łatwe
Zadanie 1.1: Calculator API
Opis: Utwórz API, które przyjmuje dwie liczby i operację (dodawanie, odejmowanie, mnożenie, dzielenie) i zwraca wynik.
Wymagania:
- GET endpoint:
/calc?a=10&b=5&op=addzwraca15 - Obsługiwane operacje:
add,sub,mul,div - Zwróć błąd 400, jeśli operacja jest nieznana
- Obsłuż dzielenie przez zero (zwróć błąd)
Podpowiedź:
- Pobierz
a,biopz query parameters - Użyj switch do obsługi różnych operacji
- Zwróć wynik jako JSON
Zadanie 1.2: Echo Server
Opis: Utwórz serwer, który odbiera tekst i go powtarza.
Wymagania:
- POST
/echoprzyjmuje JSON:{„text”: „hello”} - Zwraca:
{„echo”: „hello”, „length”: 5} - GET
/echo/hellozwraca:{„text”: „hello”}
Podpowiedź:
- Utwórz Record do deserializacji JSON
- Zwróć JSON za pomocą
ctx.json()
Zadanie 1.3: Time Server
Opis: Utwórz endpoint, który zwraca aktualny czas i datę.
Wymagania:
- GET
/timezwraca:{„time”: „14:30:45”, „date”: „2026-05-25”} - GET
/time/milliszwraca:{„millis”: 1748209845000}
Podpowiedź:
- Użyj
LocalDateTimelubSystem.currentTimeMillis() - Zwróć JSON
Zadanie 1.4: Counter API
Opis: Utwórz API licznika, który można zwiększać i resetować.
Wymagania:
- GET
/counter- zwraca obecną wartość - POST
/counter/increment- zwiększa o 1 - POST
/counter/decrement- zmniejsza o 1 - POST
/counter/reset- zeruje
Podpowiedź:
- Przechowuj licznik jako statyczne pole klasy
- Synchronizuj dostęp, jeśli będzie wiele żądań
Zadanie 1.5: Hello World Widget
Opis: Utwórz prostą stronę HTML z przyciskiem, który wyśle request do backendu.
Wymagania:
- Serwuj
index.htmlze strony głównej - Frontend: przycisk
Click me - Backend: GET
/api/hellozwraca{„message”: „Hello from backend!”} - Frontend: wyświetla odpowiedź w alertu
Poziom 2 - Zadania średnie
Zadanie 2.1: Book Library API
Opis: Utwórz API dla biblioteki książek z CRUD operacjami.
Wymagania:
- Record
Bookz polami: id, title, author, year, available (boolean) - GET
/api/books- lista wszystkich - GET
/api/books/{id}- szczegóły jednej - POST
/api/books- dodaj nową - PUT
/api/books/{id}- aktualizuj - DELETE
/api/books/{id}- usuń - Obsłuż błędy 404, 400
Wskazówki:
- Przechowuj książki w
Map<Integer, Book> - Dla każdej operacji ustaw odpowiedni status HTTP
- Zwróć JSON
Zadanie 2.2: User Registration
Opis: Utwórz system rejestracji użytkowników z walidacją.
Wymagania:
- POST
/api/registerz{„email”: „…”, „password”: „…”} - Walidacja: email musi zawierać
@, hasło min 8 znaków - Zwróć błąd 400 jeśli walidacja nie pasa
- Zwróć ID użytkownika jeśli sukces (status 201)
- Email nie może się powtarzać (status 409)
Wskazówki:
- Przechowuj użytkowników w
Map - Waliduj email prostym regex:
email.contains(„@”) - Obsługuj exceptions z Map
Zadanie 2.3: Article Filtering
Opis: Utwórz API do artykułów z możliwością filtrowania.
Wymagania:
- GET
/api/articles- wszystkie artykuły - GET
/api/articles?category=tech- filtrowanie po kategorii - GET
/api/articles?author=John- filtrowanie po autorze - GET
/api/articles?limit=5- ograniczenie liczby wyników - Kombinowanie:
/api/articles?category=tech&limit=3
Wskazówki:
- Pobierz query parameters
- Filtruj listę za pomocą
stream().filter() - Ogranicz wyniki za pomocą
limit()
Zadanie 2.4: API with Logging
Opis: Dodaj logging do dowolnego API z wcześniejszych zadań.
Wymagania:
- Loguj każde żądanie:
[INCOMING] GET /api/books - Loguj czas przetwarzania:
[DONE] 200 OK (12ms) - Loguj błędy:
[ERROR] 404 Not Found
Wskazówki:
- Użyj
config.routes.before()iconfig.routes.after() - Przechowuj
startTimewctx.attribute() - System.out.println lub logger SLF4J
Zadanie 2.5: Protected API
Opis: Utwórz API, które wymaga autentykacji tokenem.
Wymagania:
- Publiczny endpoint: GET
/api/public(bez tokenu) - Chroniony endpoint: GET
/api/secret(wymaga tokenu) - Token przesyłany w nagłówku:
Authorization: Bearer TOKEN123 - Zwróć 401 bez ważnego tokenu
- Zwróć 200 i dane z ważnym tokenem
Wskazówki:
- Używaj
config.routes.before(„/api/secret”, …)do walidacji - Pobierz nagłówek:
ctx.header(„Authorization”) - Sprawdź format
Bearer …
Poziom 3 - Zadania trudne
Zadanie 3.1: Database Integration (SQLite)
Opis: Zintegruj Javalin z bazą SQLite do trwałego przechowywania danych.
Wymagania:
- Dodaj zależność SQLite do Maven
- Utwórz tabelę
notes(id, title, content, created_at) - GET
/api/notes- pobierz z bazy - POST
/api/notes- zapisz w bazie - PUT
/api/notes/{id}- aktualizuj w bazie - DELETE
/api/notes/{id}- usuń z bazy
Wskazówki:
- Użyj JDBC lub biblioteki jak jOOQ/Hibernate
- Obsłuż
SQLException - Zamykaj połączenia (try-with-resources)
Zadanie 3.2: Pagination
Opis: Zaimplementuj paginację dla API zwracającego dużą liczbę wyników.
Wymagania:
- GET
/api/products?page=1&size=10- pierwsza strona, 10 wyników - Zwróć:
{„data”: […], „page”: 1, „size”: 10, „total”: 47} - Jeśli page jest poza zakresem, zwróć 400
- Default: page=1, size=10
Wskazówki:
- Oblicz offset:
(page - 1) * size - Używaj
stream().skip().limit() - Waliduj parametry
Zadanie 3.3: Multi-Language Support
Opis: Utwórz API, które zwraca wiadomości w różnych językach.
Wymagania:
- GET
/api/message?lang=enzwraca:{„text”: „Hello”} - GET
/api/message?lang=plzwraca:{„text”: „Cześć”} - GET
/api/message?lang=frzwraca:{„text”: „Bonjour”} - Domyślny: angielski
- Nieznany język: zwróć 400
Wskazówki:
- Przechowuj wiadomości w
Map<String, Map<String, String» - Lub plik properties dla każdego języka
- Przechowaj:
lang→key→value
Zadanie 3.4: Rate Limiting
Opis: Zaimplementuj rate limiting - ograniczenie liczby żądań na IP.
Wymagania:
- Max 10 żądań na minutę z jednego IP
- Nagłówek
X-RateLimit-Limit: 10 - Nagłówek
X-RateLimit-Remaining: 7 - Po przekroczeniu: zwróć 429 Too Many Requests
Wskazówki:
- Pobierz IP:
ctx.ip() - Przechowuj licznik i timestamp w
Map - Czy minuta minęła? Zresetuj licznik
- Załaduj w
before()
Zadanie 3.5: WebSocket Chat
Opis: Utwórz prosty chat z WebSocket (opcjonalne - zaawansowane).
Wymagania:
- Serwer Javalin obsługuje WebSocket
- Frontend: strona HTML z polem do wpisywania
- Wiadomości wysyłane w real-time do wszystkich połączonych klientów
- Przechowuj historię ostatnich 10 wiadomości
Wskazówki:
app.ws()do obsługi WebSocket- Przechowuj sesje w
Set<WsContext> - Broadcast: pętla po wszystkich sesjach
Dodatkowe wyzwania
Zadanie Bonus 1: Full Stack Todo App
Utwórz kompletną aplikację TODO z:
- Frontend: HTML/CSS/JavaScript
- Backend API: CRUD operacje
- Baza danych: SQLite
- Autoryzacja: prostokrotny token
- Walidacja: po stronie frontend i backend
- Błędy: elegancka obsługa
- Logging: pełne logowanie operacji
Zadanie Bonus 2: RESTful API dla E-Shopu
Utwórz API dla sklepu internetowego:
- Produkty: GET, POST, PUT, DELETE, search, filtrowanie
- Koszyk: dodaj, usuń, wyczyść, podsumowanie
- Zamówienia: CREATE, status, historia
- Użytkownicy: rejestracja, login (token)
- Walidacja, obsługa błędów, logging
Zadanie Bonus 3: Microservice Architecture
Utwórz dwa mikroserwisy komunikujące się ze sobą:
- Serwis 1 (UserService): zarządzanie użytkownikami
- Serwis 2 (OrderService): zarządzanie zamówieniami
- OrderService wysyła żądania do UserService
- Obsłuż timeout i błędy komunikacji
- Zaloguj wszystkie komunikaty między serwisami
Wskazówki do rozwiązywania zadań
Ogólne:
1. Przeczytaj zadanie do końca 2. Zidentyfikuj wymagane endpoints 3. Zaplanuj strukturę (Records, kontrolery, etc.) 4. Zacznij od prostych przypadków, potem rozszerz 5. Testuj każdy endpoint w Postmanie
Obsługa błędów:
- Zawsze obsłuż wyjątki
- Zwróć JSON z opisem błędu:
{„error”: „…”} - Ustaw odpowiedni status HTTP
Testowanie:
- cURL:
curl -X GET http://localhost:8080/api/… - Postman: wygodny GUI
- IntelliJ HTTP Client: wbudowany w IDE
Debugowanie:
- Dodaj
System.out.println()do logowania - Użyj debuggera (F5 w IntelliJ)
- Sprawdź Network tab w DevTools przeglądarki
Rozwiązania
Rozwiązania do wszystkich zadań będą dostępne po zajęciach.
Do każdego rozwiązania dołączony będzie opis:
- Jakie koncepty Javalin zostały użyte
- Jakie problemy mogą się pojawić
- Jak można ulepszyć kod
- Alternatywne podejścia
Powodzenia! 🚀