Jak napisać prosty REST API w Spring Boot dla początkujących
- Wprowadzenie do prostego REST API w Spring Boot
- Dlaczego warto w 2026 umieć pisać REST API w Spring Boot?
- Przygotowanie środowiska developerskiego
- Tworzenie projektu Spring Boot w Spring Initializr
- Pierwszy endpoint REST w Spring Boot
- Dodanie modelu danych Task i warstwy serwisu
- Kontroler TaskController – pełne REST API CRUD
- Testowanie REST API z użyciem curl i Postmana
- Co dalej po pierwszym REST API w Spring Boot?
Wprowadzenie do prostego REST API w Spring Boot
Zastanawiasz się, jak napisać prosty REST API w Spring Boot dla początkujących backend 2026 i od czego w ogóle zacząć? Umiejętność budowania API to dziś fundament pracy programisty backend, niezależnie od tego, czy tworzysz aplikacje mobilne, SPA, czy systemy mikrousług. Spring Boot pozwala wejść w ten świat szybko i bez bolesnej konfiguracji.
W tym artykule krok po kroku zbudujesz swoje pierwsze REST API w Spring Boot. Skupisz się na praktyce, tworząc działający projekt, który obsługuje proste operacje CRUD. Przejdziesz przez przygotowanie środowiska, wygenerowanie szkieletu aplikacji, implementację endpointów oraz testowanie API.
Wyobraź sobie, że Twoja aplikacja to restauracja, a dane to potrawy. REST API jest menu i kelnerem, który pośredniczy między „klientem” (frontem, aplikacją mobilną) a „kuchnią” (serwerem). Dzięki jasno zdefiniowanym zasadom komunikacji różne systemy mogą wymieniać dane w przewidywalny i uporządkowany sposób.
Spring Boot to „król” ekosystemu Javy, który realizuje zasadę konwencja ponad konfiguracją. Oznacza to, że zamiast walczyć z XML-ami i rozbudowanym setupem, skupiasz się na logice biznesowej. Framework jest masowo wykorzystywany w firmach produktowych i software house’ach, a jego znajomość pozostanie bardzo cenna także w 2026 roku.

Dlaczego warto w 2026 umieć pisać REST API w Spring Boot?
REST API to dziś standard komunikacji pomiędzy serwerem a klientem. Gdy aplikacja mobilna pobiera listę produktów, panel administracyjny zapisuje nowe dane, a mikroserwisy wymieniają informacje – za kulisami zazwyczaj działa właśnie REST. To uniwersalny sposób na expose’owanie danych i funkcjonalności do świata zewnętrznego.
Spring Boot natomiast zapewnia gotową infrastrukturę, dzięki której wdrożenie REST API sprowadza się w dużej mierze do pisania klas kontrolerów, serwisów i modeli. Nie musisz ręcznie konfigurować serwera aplikacyjnego ani zależności – projekt startuje w kilka minut.
Znajomość Spring Boot i REST API przekłada się bezpośrednio na Twoją atrakcyjność na rynku pracy. Wiele rekrutacji backendowych w Javie zakłada zadania właśnie z implementacji prostych endpointów, obsługi CRUD oraz integracji z bazą danych. Ucząc się tego dziś, inwestujesz w kompetencje, które będą aktualne również w 2026 roku i później.
Przygotowanie środowiska developerskiego
Zanim napiszesz pierwszy endpoint, potrzebujesz podstawowego środowiska do pracy ze Spring Boot i Javą. Skonfigurujesz kilka kluczowych narzędzi, które będą fundamentem Twojej dalszej nauki programowania backend.
Niezbędne komponenty: JDK, Maven/Gradle, IDE
Do pracy z Spring Boot potrzebujesz przede wszystkim:
- Java Development Kit (JDK) – zalecana jest aktualna stabilna wersja, np. Java 17 lub nowsza. JDK dostarcza kompilator, runtime i narzędzia konieczne do uruchamiania aplikacji.
- Narzędzie do budowania projektu – najpopularniejsze to Maven i Gradle. W tym przykładzie użyjesz Mavena, który jest standardem w wielu projektach komercyjnych.
- IDE do Javy – wygodne środowisko pracy znacznie przyspiesza naukę. Masz kilka sprawdzonych opcji:
- IntelliJ IDEA Community Edition – darmowe, bardzo popularne i dobrze zoptymalizowane pod Javę,
- Visual Studio Code z rozszerzeniami do Javy – lekkie i elastyczne,
- Eclipse – klasyk w świecie Javy, również darmowy.
Po zainstalowaniu JDK i Mavena/Gradle upewnij się, że są dostępne w zmiennej środowiskowej PATH. Następnie zainstaluj wybrane IDE, w którym otworzysz generowany za chwilę projekt Spring Boot.
Sprawdzenie instalacji i gotowości środowiska
Po instalacji możesz szybko zweryfikować konfigurację z poziomu terminala lub wiersza poleceń:
- Sprawdzenie wersji Javy:
bash java -version - Sprawdzenie wersji Mavena (jeśli korzystasz z Mavena lokalnie):
bash mvn -version
Jeśli obie komendy zwracają poprawne wersje, środowisko jest gotowe. Teraz możesz przejść do wygenerowania szkieletu aplikacji Spring Boot, korzystając z Spring Initializr.
Tworzenie projektu Spring Boot w Spring Initializr
Aby nie zaczynać od pustego katalogu i ręcznej konfiguracji, wykorzystasz Spring Initializr, który generuje gotowy do uruchomienia projekt. Dzięki temu szybko zobaczysz działające REST API w praktyce.
Konfiguracja projektu w Spring Initializr
- Otwórz przeglądarkę i przejdź do narzędzia Spring Initializr.
- W sekcji ustawień projektu skonfiguruj podstawowe elementy:
- Project:
Maven Project - Language:
Java - Spring Boot: najnowsza stabilna wersja, np.
3.x.x - Wypełnij metadane projektu:
- Group:
pl.radoszewski(lub np.com.example) - Artifact:
my-first-api - Name:
my-first-api - Description:
Proste REST API dla portalu Radoszewski.pl - Package Name:
pl.radoszewski.myfirstapi - Packaging:
Jar - Java: wersja zgodna z zainstalowanym JDK (np.
17)
Następnie przejdź do sekcji zależności, gdzie wybierzesz biblioteki potrzebne do stworzenia prostego REST API.
Dodanie zależności i import projektu do IDE
W polu zależności kliknij Add Dependencies i wyszukaj:
- Spring Web – to kluczowy starter, który dodaje obsługę REST, kontrolerów, wbudowanego serwera i niezbędnych komponentów sieciowych.
Po dodaniu zależności kliknij Generate, aby pobrać wygenerowany projekt jako archiwum .zip. Rozpakuj go w wybranym katalogu i otwórz w IDE:
- W IntelliJ IDEA użyj
File -> Openi wskaż folder projektu, - IDE zaimportuje projekt jako projekt Maven, pobierze zależności i zbuduje go.
Po zakończonym imporcie w strukturze katalogów znajdziesz m.in. klasę MyFirstApiApplication.java – to główny punkt startowy aplikacji Spring Boot.
Pierwszy endpoint REST w Spring Boot
Masz już gotowy szkielet aplikacji, więc czas dodać pierwszy, bardzo prosty endpoint REST. Dzięki adnotacjom Spring Boot konfiguracja sprowadza się do kilku linijek kodu w kontrolerze.
Tworzenie kontrolera HelloController
Przejdź do katalogu src/main/java/pl/radoszewski/myfirstapi i utwórz nową klasę HelloController.java:
package pl.radoszewski.myfirstapi;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String helloWorld() {
return "Cześć, świecie z Radoszewski.pl!";
}
}
W tej klasie dzieje się kilka ważnych rzeczy:
@RestControllerinformuje Springa, że klasa udostępnia endpointy REST i domyślnie zwraca dane bezpośrednio w odpowiedzi HTTP.@GetMapping("/hello")mapuje żądania HTTP GET pod adresem/hellona metodęhelloWorld.- Metoda
helloWorld()zwraca prosty tekst, który zostanie przesłany jako odpowiedź do klienta.
To najprostszy możliwy przykład REST API w Spring Boot, idealny na początek nauki backendu w Javie.
Uruchamianie aplikacji i pierwszy test
Znajdź klasę MyFirstApiApplication.java i uruchom jej metodę main z poziomu IDE. W konsoli zobaczysz logi startowe Spring Boot oraz informację o uruchomieniu wbudowanego serwera na porcie 8080.
Po starcie aplikacji możesz przetestować endpoint na kilka sposobów:
- W przeglądarce wpisz adres:
text http://localhost:8080/hello - Powinieneś zobaczyć tekst:
text Cześć, świecie z Radoszewski.pl!
To pierwszy dowód, że konfiguracja Spring Boot działa, a Ty właśnie uruchomiłeś swoje pierwsze REST API. W kolejnych krokach rozbudujesz projekt o model danych, warstwę serwisu i pełne operacje CRUD.
Dodanie modelu danych Task i warstwy serwisu
Sam tekst „Cześć, świecie” to za mało, by poczuć prawdziwą moc Spring Boot. Zbudujesz więc proste API do zarządzania zadaniami (tasks). Na razie dane będą przechowywane w pamięci, bez bazy danych, żebyś mógł skupić się na podstawach API.

Definicja modelu Task
W pakiecie pl.radoszewski.myfirstapi utwórz nowy pakiet model, a w nim klasę Task.java:
package pl.radoszewski.myfirstapi.model;
public class Task {
private Long id;
private String title;
private String description;
private boolean completed;
// Konstruktor
public Task(Long id, String title, String description, boolean completed) {
this.id = id;
this.title = title;
this.description = description;
this.completed = completed;
}
// Pusty konstruktor (potrzebny Springowi do deserializacji)
public Task() {
}
// Gettery i Settery
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean isCompleted() {
return completed;
}
public void setCompleted(boolean completed) {
this.completed = completed;
}
}
Ta klasa reprezentuje pojedyncze zadanie w Twoim systemie. Zawiera:
id– identyfikator zadania,title– krótki tytuł,description– opis,completed– informację, czy zadanie jest zakończone.
Pusty konstruktor jest niezbędny, aby Spring (i biblioteka Jackson) mógł deserializować obiekty z JSON-a przychodzącego w żądaniu HTTP.
Implementacja serwisu TaskService
Kolejnym krokiem jest warstwa serwisu, która będzie zarządzała listą zadań. W pakiecie pl.radoszewski.myfirstapi utwórz podpakiet service i klasę TaskService.java:
package pl.radoszewski.myfirstapi.service;
import pl.radoszewski.myfirstapi.model.Task;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicLong;
@Service
public class TaskService {
private final List<Task> tasks = new ArrayList<>();
private final AtomicLong nextId = new AtomicLong(1); // Do generowania unikalnych ID
public TaskService() {
// Dodajemy kilka początkowych zadań
tasks.add(new Task(nextId.getAndIncrement(), "Napisz pierwszy wpis na bloga", "Stwórz kompleksowy artykuł o Spring Boot", false));
tasks.add(new Task(nextId.getAndIncrement(), "Zoptymalizuj wpis pod SEO", "Dodaj słowa kluczowe i nagłówki", false));
tasks.add(new Task(nextId.getAndIncrement(), "Zrób kawę", "Mocną i aromatyczną!", true));
}
public List<Task> getAllTasks() {
return new ArrayList<>(tasks); // Zwracamy kopię, aby lista wewnętrzna była bezpieczna
}
public Optional<Task> getTaskById(Long id) {
return tasks.stream()
.filter(task -> task.getId().equals(id))
.findFirst();
}
public Task addTask(Task task) {
task.setId(nextId.getAndIncrement());
tasks.add(task);
return task;
}
public Optional<Task> updateTask(Long id, Task updatedTask) {
return getTaskById(id).map(existingTask -> {
existingTask.setTitle(updatedTask.getTitle());
existingTask.setDescription(updatedTask.getDescription());
existingTask.setCompleted(updatedTask.isCompleted());
return existingTask;
});
}
public boolean deleteTask(Long id) {
return tasks.removeIf(task -> task.getId().equals(id));
}
}
Najważniejsze elementy tego serwisu:
@Service– adnotacja, która oznacza komponent logiki biznesowej zarządzany przez Springa.List<Task> tasks– prosta „baza danych” w pamięci, przechowująca listę zadań.AtomicLong nextId– generator unikalnych identyfikatorów dla nowych zadań.- Metody CRUD:
getAllTasks()– zwraca wszystkie zadania,getTaskById()– pobiera zadanie po ID,addTask()– dodaje nowe zadanie,updateTask()– aktualizuje istniejące zadanie,deleteTask()– usuwa zadanie po ID.
Taka architektura z wyraźnym podziałem na model i serwis jest dobrym wprowadzeniem do późniejszego korzystania z baz danych i dodatkowych warstw (np. repozytoriów).
Kontroler TaskController – pełne REST API CRUD
Masz już model danych oraz logikę biznesową. Teraz trzeba wystawić je na zewnątrz w formie REST API. Zrobisz to, tworząc kontroler TaskController, który będzie obsługiwał żądania HTTP i korzystał z serwisu.
Konfiguracja kontrolera i mapowanie endpointów
W pakiecie pl.radoszewski.myfirstapi utwórz podpakiet controller, a w nim klasę TaskController.java. Opcjonalnie możesz usunąć wcześniejszy HelloController, aby projekt był bardziej uporządkowany:
package pl.radoszewski.myfirstapi.controller;
import pl.radoszewski.myfirstapi.model.Task;
import pl.radoszewski.myfirstapi.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/tasks") // Wszystkie endpointy w tym kontrolerze będą poprzedzone /api/tasks
public class TaskController {
private final TaskService taskService;
@Autowired // Spring sam wstrzyknie instancję TaskService
public TaskController(TaskService taskService) {
this.taskService = taskService;
}
@GetMapping // GET /api/tasks
public List<Task> getAllTasks() {
return taskService.getAllTasks();
}
@GetMapping("/{id}") // GET /api/tasks/{id}
public ResponseEntity<Task> getTaskById(@PathVariable Long id) {
return taskService.getTaskById(id)
.map(task -> new ResponseEntity<>(task, HttpStatus.OK))
.orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
@PostMapping // POST /api/tasks
public ResponseEntity<Task> addTask(@RequestBody Task task) {
Task newTask = taskService.addTask(task);
return new ResponseEntity<>(newTask, HttpStatus.CREATED);
}
@PutMapping("/{id}") // PUT /api/tasks/{id}
public ResponseEntity<Task> updateTask(@PathVariable Long id, @RequestBody Task task) {
return taskService.updateTask(id, task)
.map(updatedTask -> new ResponseEntity<>(updatedTask, HttpStatus.OK))
.orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
@DeleteMapping("/{id}") // DELETE /api/tasks/{id}
public ResponseEntity<Void> deleteTask(@PathVariable Long id) {
if (taskService.deleteTask(id)) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT); // Brak treści, ale sukces
}
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
W tym kontrolerze warto zwrócić uwagę na kilka elementów:
@RequestMapping("/api/tasks")– ustawia wspólny prefiks URL-a dla wszystkich endpointów kontrolera.- Konstruktor z adnotacją
@Autowired– Spring automatycznie wstrzykuje instancjęTaskService, realizując Dependency Injection. - Metody opatrzone
@GetMapping,@PostMapping,@PutMapping,@DeleteMapping– każda odpowiada konkretnej operacji HTTP na zasobieTask.
Dzięki temu powstało kompletne REST API dla zadań, które umożliwia tworzenie, odczytywanie, aktualizację oraz usuwanie danych.
Adnotacje, ResponseEntity i statusy HTTP
Każda metoda operująca na pojedynczym zadaniu zwraca ResponseEntity, co pozwala kontrolować zarówno treść odpowiedzi, jak i kod statusu HTTP. To ważne elementy profesjonalnego API:
@PathVariable– odczytuje fragment ścieżki URL jako parametr metody (np.idw/api/tasks/{id}).@RequestBody– informuje Springa, że parametrem jest JSON z ciała żądania, który należy zdeserializować do obiektuTask.ResponseEntity– umożliwia ustawianie kodów:HttpStatus.OK(200) – gdy operacja się powiodła,HttpStatus.CREATED(201) – gdy utworzono nowy zasób,HttpStatus.NO_CONTENT(204) – gdy usunięto zasób bez treści odpowiedzi,HttpStatus.NOT_FOUND(404) – gdy nie znaleziono zasobu o podanym ID.
Tak zaprojektowane API jest czytelne, spójne i zgodne z dobrymi praktykami REST, co ma duże znaczenie w realnych projektach backendowych.
Testowanie REST API z użyciem curl i Postmana
Po zaimplementowaniu API czas sprawdzić, czy wszystko działa zgodnie z oczekiwaniami. Możesz użyć zarówno prostych narzędzi terminalowych, jak i wygodnego interfejsu graficznego.
Szybkie testy w terminalu za pomocą curl
Upewnij się, że aplikacja jest uruchomiona na porcie 8080, a następnie wykonaj poniższe komendy:
- Pobranie wszystkich zadań (GET):
bash curl http://localhost:8080/api/tasks - Pobranie zadania po ID (GET):
bash curl http://localhost:8080/api/tasks/1 - Dodanie nowego zadania (POST):
bash curl -X POST -H "Content-Type: application/json" -d '{"title":"Nauka Spring Boota", "description":"Kontynuuj naukę i twórz nowe projekty", "completed":false}' http://localhost:8080/api/tasks - Aktualizacja zadania (PUT):
bash curl -X PUT -H "Content-Type: application/json" -d '{"title":"Nauka Spring Boota - zakończona", "description":"Spring Boot opanowany!", "completed":true}' http://localhost:8080/api/tasks/4 - Usunięcie zadania (DELETE):
bash curl -X DELETE http://localhost:8080/api/tasks/4
Po każdym żądaniu zobaczysz w odpowiedzi JSON z zadaniem lub odpowiedni kod HTTP. To prosty sposób na walidację logiki CRUD bez wychodzenia z terminala.
Testowanie API w Postmanie lub Insomnia
Jeśli wolisz narzędzie z GUI, idealnym wyborem będzie Postman lub Insomnia. Pozwalają one wygodnie wysyłać żądania HTTP i analizować odpowiedzi:
- Utwórz nowe żądanie i ustaw metodę HTTP (GET, POST, PUT, DELETE).
- W polu adresu wpisz URL, np.:
http://localhost:8080/api/taskshttp://localhost:8080/api/tasks/1- Dla metod POST i PUT:
- Przejdź do zakładki
Body, - Wybierz
raworaz formatJSON, - Wpisz treść żądania, np.:
json { "title": "Nowe zadanie", "description": "Test z Postmana", "completed": false } - Kliknij
Sendi sprawdź odpowiedź oraz status HTTP.
W ten sposób możesz szybko zweryfikować wszystkie endpointy, sprawdzając poprawność danych i zachowanie API w różnych scenariuszach.
Co dalej po pierwszym REST API w Spring Boot?
Stworzyłeś już działające proste REST API w Spring Boot dla początkujących backend 2026, obsługujące pełen zestaw operacji CRUD na zasobie Task. To solidny fundament, ale świat backendu oferuje o wiele więcej możliwości rozwoju.
Możesz kontynuować naukę w kilku naturalnych kierunkach:
- Integracja z bazą danych – zamiast listy w pamięci użyj Spring Data JPA i bazy H2, PostgreSQL lub MySQL. Pozwoli to utrwalać dane między restartami aplikacji.
- Obsługa błędów – wprowadź globalny mechanizm obsługi wyjątków i zwracaj ustrukturyzowane komunikaty błędów w formacie JSON.
- Walidacja danych – korzystając z adnotacji typu
@NotBlankczy@Size, możesz zadbać o poprawność danych wejściowych. - Bezpieczeństwo z Spring Security – dodaj uwierzytelnianie i autoryzację, aby chronić swoje endpointy.
- Testy jednostkowe i integracyjne – naucz się pisać testy dla serwisów i kontrolerów, aby utrzymać wysoką jakość kodu.
- Dokumentacja API – użyj Swagger/OpenAPI do generowania interaktywnej dokumentacji, z której skorzystają inni programiści.
Nie zatrzymuj się na pierwszym działającym projekcie. Eksperymentuj, dodawaj kolejne funkcjonalności i buduj coraz bardziej zaawansowane usługi. Z takim fundamentem wejście w świat mikrousług i profesjonalnego backendu w Javie stanie się znacznie prostsze.