Ślad: • zasoby • 11_javalin_zadania

Javalin - Zadania dla studentów

Writing /home/grochu/public_html/wiki/data/cache/5/5a1e09b1d39c0832c4c7115c2b7ce7da.i failed
Unable to save cache file. Hint: disk full; file permissions; safe_mode setting.
Writing /home/grochu/public_html/wiki/data/cache/5/5a1e09b1d39c0832c4c7115c2b7ce7da.metadata failed
Writing /home/grochu/public_html/wiki/data/cache/a/a78cbd33a6c694b3f51b5258479b5b5a.i failed
Writing /home/grochu/public_html/wiki/data/meta/zajecia/java/sidebar.meta failed
Unable to save metadata file. Hint: disk full; file permissions; safe_mode setting.
Writing /home/grochu/public_html/wiki/data/cache/5/5a1e09b1d39c0832c4c7115c2b7ce7da.i failed
Unable to save cache file. Hint: disk full; file permissions; safe_mode setting.

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=add zwraca 15
  • 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, b i op z 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 /echo przyjmuje JSON: {„text”: „hello”}
  • Zwraca: {„echo”: „hello”, „length”: 5}
  • GET /echo/hello zwraca: {„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 /time zwraca: {„time”: „14:30:45”, „date”: „2026-05-25”}
  • GET /time/millis zwraca: {„millis”: 1748209845000}

Podpowiedź:

  • Użyj LocalDateTime lub System.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.html ze strony głównej
  • Frontend: przycisk Click me
  • Backend: GET /api/hello zwraca {„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 Book z 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/register z {„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() i config.routes.after()
  • Przechowuj startTime w ctx.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=en zwraca: {„text”: „Hello”}
  • GET /api/message?lang=pl zwraca: {„text”: „Cześć”}
  • GET /api/message?lang=fr zwraca: {„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:

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! 🚀