RESTful Web Services - REST Application Basics 🚀
The Restaurant Story 🍽️
Imagine you own a magical restaurant. Customers can’t come inside. Instead, they stand outside and shout what they want through a special window. Your waiters listen, get things from the kitchen, and bring them back.
That’s exactly how REST works!
- The customer = Your app (client)
- The window = The internet (HTTP)
- The waiter = REST API
- The kitchen = Your server and database
Let’s learn how to build this magical restaurant with Jakarta REST!
1. Jakarta REST Overview 📋
What is Jakarta REST?
Jakarta REST (formerly JAX-RS) is a set of rules for building web services in Java. It helps your Java program talk to other programs over the internet.
Simple Example:
- Your phone app needs weather data
- It asks a server: “Hey, what’s the weather today?”
- The server sends back: “Sunny, 25°C”
- That conversation happens using REST!
Why Jakarta REST?
| Feature | What It Means |
|---|---|
| Easy to write | Use simple annotations like @GET |
| Works everywhere | Any device can talk to it |
| Standard | Everyone uses the same rules |
Real Life Example
@Path("/weather")
public class WeatherResource {
@GET
public String getWeather() {
return "Sunny, 25°C";
}
}
That’s it! You just built a mini weather service. Someone asks for /weather, and they get “Sunny, 25°C” back.
2. REST Architecture Principles 🏗️
Think of REST like the rules of our restaurant.
The 6 Magic Rules
graph TD A["REST Principles"] --> B["Client-Server"] A --> C["Stateless"] A --> D["Cacheable"] A --> E["Uniform Interface"] A --> F["Layered System"] A --> G["Code on Demand"]
Rule 1: Client-Server 🤝
The customer and kitchen are separate. The customer doesn’t need to know how the kitchen works.
Example: Your phone app doesn’t care if the server uses Java or Python. It just wants data!
Rule 2: Stateless 🧠❌
The waiter has no memory. Every order must be complete.
Bad: “I’ll have the same as yesterday” Good: “I’ll have 2 burgers with cheese”
// Each request is complete
@GET
@Path("/orders/{id}")
public Order getOrder(@PathParam("id") int id) {
return database.findOrder(id);
}
Rule 3: Cacheable 📦
Some things can be saved and reused. The menu doesn’t change every minute!
Example: Weather data can be cached for 10 minutes. No need to ask again!
Rule 4: Uniform Interface 🔧
Everyone uses the same tools:
| Tool | What It Does | Example |
|---|---|---|
| GET | Read something | Get user info |
| POST | Create something | Add new user |
| PUT | Update something | Change user name |
| DELETE | Remove something | Delete user |
Rule 5: Layered System 🎂
Like a cake! Each layer only talks to the next layer.
graph TD A["Your App"] --> B["Load Balancer"] B --> C["Server 1"] B --> D["Server 2"] C --> E["Database"] D --> E
Rule 6: Code on Demand 📱
Sometimes the server sends code to run. Like JavaScript on websites!
3. JAX-RS Application Class 🎯
What is the Application Class?
It’s the front door of your restaurant. It tells Jakarta REST: “Hey, my restaurant is open at this address!”
The Simplest Application
@ApplicationPath("/api")
public class MyRestApp
extends Application {
// That's it! No code needed inside!
}
What this does:
@ApplicationPath("/api")= Our restaurant is at/api- All your REST endpoints will start with
/api
Example URLs
If your server is at www.mysite.com:
/api/users→ Get all users/api/products→ Get all products/api/orders/123→ Get order number 123
graph TD A["@ApplicationPath#40;'/api'#41;"] --> B["/api/users"] A --> C["/api/products"] A --> D["/api/orders"]
When You Need More Control
Sometimes you want to manually say which waiters (resources) work today:
@ApplicationPath("/api")
public class MyRestApp extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes =
new HashSet<>();
classes.add(UserResource.class);
classes.add(OrderResource.class);
return classes;
}
}
4. Resource Classes 👨🍳
What is a Resource Class?
A Resource Class is like a specific waiter who handles one type of order. The “pizza waiter” only handles pizza orders!
Creating a Resource Class
@Path("/books")
public class BookResource {
// All book-related stuff goes here
}
Key points:
@Path("/books")= This waiter handles/api/booksrequests- It’s just a regular Java class
- No need to extend anything!
A Complete Example
@Path("/pets")
public class PetResource {
private List<Pet> pets =
new ArrayList<>();
@GET
public List<Pet> getAllPets() {
return pets;
}
@GET
@Path("/{id}")
public Pet getPet(@PathParam("id") int id) {
return pets.get(id);
}
@POST
public void addPet(Pet pet) {
pets.add(pet);
}
}
How URLs Map to Methods
| URL | HTTP Method | Java Method |
|---|---|---|
/api/pets |
GET | getAllPets() |
/api/pets/5 |
GET | getPet(5) |
/api/pets |
POST | addPet(pet) |
graph TD A["Client Request"] --> B{"/api/pets"} B -->|GET| C["getAllPets"] B -->|POST| D["addPet"] B -->|GET /5| E["getPet 5"]
5. Resource Methods 🎬
What is a Resource Method?
Resource Methods are the actual actions your waiter performs. Taking orders, bringing food, giving the bill!
The HTTP Method Annotations
@Path("/tasks")
public class TaskResource {
@GET // Read
public List<Task> getTasks() { }
@POST // Create
public void createTask(Task t) { }
@PUT // Update
@Path("/{id}")
public void updateTask(
@PathParam("id") int id,
Task t) { }
@DELETE // Delete
@Path("/{id}")
public void deleteTask(
@PathParam("id") int id) { }
}
Getting Data from Requests
From the URL Path
@GET
@Path("/users/{userId}")
public User getUser(
@PathParam("userId") int id) {
return userService.find(id);
}
URL: /api/users/42 → id = 42
From Query Parameters
@GET
@Path("/search")
public List<Item> search(
@QueryParam("q") String query,
@QueryParam("limit") int limit) {
return itemService.search(query, limit);
}
URL: /api/search?q=phone&limit=10
Returning Different Data Types
Return Text
@GET
@Produces("text/plain")
public String hello() {
return "Hello World!";
}
Return JSON
@GET
@Produces("application/json")
public User getUser() {
return new User("Alice", 25);
}
Result: {"name":"Alice","age":25}
Receiving Data
@POST
@Consumes("application/json")
public void createUser(User user) {
userService.save(user);
}
The client sends JSON, and Jakarta REST automatically converts it to a User object!
Putting It All Together 🎁
graph TD A["Application Class"] -->|defines path /api| B["Resource Classes"] B --> C["UserResource"] B --> D["ProductResource"] C --> E["@GET getUser#40;#41;"] C --> F["@POST createUser#40;#41;"] D --> G["@GET getProducts#40;#41;"]
The Complete Picture
- Application Class → Opens the restaurant at
/api - Resource Classes → Different waiters for different things
- Resource Methods → The actual work each waiter does
Mini Project: A Simple Todo API
// 1. The Application
@ApplicationPath("/api")
public class TodoApp extends Application {}
// 2. The Resource Class
@Path("/todos")
public class TodoResource {
static List<String> todos =
new ArrayList<>();
// 3. Resource Methods
@GET
@Produces("application/json")
public List<String> getAll() {
return todos;
}
@POST
@Consumes("text/plain")
public void add(String todo) {
todos.add(todo);
}
@DELETE
@Path("/{index}")
public void remove(
@PathParam("index") int i) {
todos.remove(i);
}
}
You Did It! 🎉
You now understand:
✅ Jakarta REST = Rules for building web services in Java
✅ REST Principles = Client-Server, Stateless, Cacheable, Uniform Interface, Layered, Code on Demand
✅ Application Class = The front door with @ApplicationPath
✅ Resource Classes = Specialized handlers with @Path
✅ Resource Methods = Actions using @GET, @POST, @PUT, @DELETE
Remember the restaurant:
- Your Application is the front door
- Your Resource Classes are the waiters
- Your Resource Methods are the actions
- REST principles are the rules everyone follows
Now go build something amazing! 🚀
