Skip to content

Latest commit

 

History

History
173 lines (145 loc) · 4.28 KB

File metadata and controls

173 lines (145 loc) · 4.28 KB

QuoteAPI

Aplikacja do zarządzania cytatami w PostgreSQL, z dwoma interfejsami:

  • REST API (odczyt cytatów),
  • CLI (dodawanie, edycja, usuwanie, import).

Moduły

  • core - model domenowy, repozytorium JPA, serwis biznesowy.
  • api - Spring Boot REST API.
  • cli - aplikacja Spring Shell uruchamiana z JAR.

Wymagania

  • Java 21
  • Maven 3.9+
  • PostgreSQL

Konfiguracja

  1. Skopiuj plik środowiskowy:
cp .env.example .env
  1. Uzupełnij dane bazy w .env:
  • SPRING_DATASOURCE_URL
  • SPRING_DATASOURCE_USERNAME
  • SPRING_DATASOURCE_PASSWORD

Przykład (local):

SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/quote_db
SPRING_DATASOURCE_USERNAME=quote
SPRING_DATASOURCE_PASSWORD=quote
SPRING_JPA_HIBERNATE_DDL_AUTO=update

Uwaga: create-drop usuwa tabele przy zamykaniu aplikacji. Używaj go tylko do testów.

Budowanie

Z katalogu głównego projektu:

mvn clean package

Po buildzie CLI JAR znajduje się tutaj:

  • cli/target/cli-1.0.0.jar

Uruchomienie REST API

mvn -pl api -am spring-boot:run

Domyślnie API działa pod adresem:

  • http://localhost:8080

Endpointy API

  • GET /api/quotes - lista cytatów (paginowana)
  • GET /api/quotes/{id} - cytat po ID
  • GET /api/quotes/random - losowy cytat
  • GET /api/quotes/daily?date=<YYYY-MM-DD> - cytat dnia (ISO-8601 date)

Paginacja (GET /api/quotes)

Parametry query:

  • page - numer strony (od 0), domyślnie 0
  • size - rozmiar strony, domyślnie 20, maksymalnie 100 (większe wartości zwrócą 400)
  • sort - sortowanie, np. sort=id,asc albo wielokrotnie sort=author,asc&sort=id,desc

Przykłady:

curl "http://localhost:8080/api/quotes?page=0&size=20"
curl "http://localhost:8080/api/quotes?page=1&size=50&sort=id,asc"

Przykład:

curl "http://localhost:8080/api/quotes/daily?date=2026-02-18"

Uruchomienie CLI z JAR

Jednorazowo:

java --enable-native-access=ALL-UNNAMED -jar cli/target/cli-1.0.0.jar

Dodanie CLI do ścieżki (PATH)

PATH przechowuje katalogi, nie pliki JAR, więc dodajemy katalog z launcherem uruchamiającym ten JAR.

  1. Utwórz katalog na własne komendy:
mkdir -p "$HOME/.local/bin"
  1. W katalogu projektu ustaw zmienną z rootem repo:
PROJECT_ROOT="$(pwd)"
  1. Dodaj launcher quote-cli:
cat > "$HOME/.local/bin/quote-cli" <<SH
#!/usr/bin/env bash
set -euo pipefail
PROJECT_ROOT="$PROJECT_ROOT"
export QUOTE_API_ENV_FILE="\$PROJECT_ROOT/.env"
exec java --enable-native-access=ALL-UNNAMED -jar "\$PROJECT_ROOT/cli/target/cli-1.0.0.jar" "\$@"
SH
chmod +x "$HOME/.local/bin/quote-cli"
  1. Dodaj katalog do PATH (zsh):
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

Od tego momentu uruchamiasz CLI globalnie:

quote-cli

.env w produkcji

W produkcji ustawiaj konfigurację przez manager procesu (systemd, Docker, Kubernetes), zamiast lokalnego .env w repo.

Aplikacja obsługuje wskazanie pliku env przez QUOTE_API_ENV_FILE.

Przykład jednorazowo (CLI):

QUOTE_API_ENV_FILE=/etc/quote-api/quote-api.env quote-cli help

Przykład jednorazowo (API):

QUOTE_API_ENV_FILE=/etc/quote-api/quote-api.env java -jar api/target/api-1.0.0.jar

Komendy CLI

  • list - lista cytatów
  • add "<autor>" <pl|en> "<cytat>"
  • insert <sciezka-do-json>
  • update <id> -a "<autor>" -l <pl|en> -q "<cytat>"
  • delete <id>

Przykłady:

quote-cli add "Seneca" en "Luck is what happens when preparation meets opportunity"
quote-cli list
quote-cli update 1 -a "Marcus Aurelius"
quote-cli delete 1

Format importu JSON (insert)

Plik powinien zawierać tablicę obiektów:

[
  {
    "author": "Seneca",
    "language": "en",
    "quote": "Luck is what happens when preparation meets opportunity"
  },
  {
    "author": "Marek Aureliusz",
    "language": "pl",
    "quote": "Masz władzę nad swoim umysłem, nie nad zdarzeniami zewnętrznymi."
  }
]

Uwagi

  • Dozwolone języki w modelu domenowym: pl, en.
  • API odpowiada tylko za odczyt, operacje zapisu realizuje CLI.

Efekt bezpieczeństwa

  • Domyślnie size=20, więc GET /api/quotes nie spróbuje już ściągnąć całej tabeli.
  • Każde size > 100 dostanie 400 Bad Request z czytelnym komunikatem.
  • To samo dla page < 0 lub size < 1.