Skip to content

Commit 177c721

Browse files
authored
Rest API in Java (#18428)
* Rest API in Java * Addressing the feedback comments
1 parent b86b3a9 commit 177c721

File tree

2 files changed

+203
-0
lines changed

2 files changed

+203
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package com.baeldung.rest;
2+
3+
import com.sun.net.httpserver.HttpExchange;
4+
import com.sun.net.httpserver.HttpHandler;
5+
import com.sun.net.httpserver.HttpServer;
6+
import java.io.*;
7+
import java.net.InetSocketAddress;
8+
import java.nio.charset.StandardCharsets;
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
12+
public class RestApiServer implements HttpHandler {
13+
14+
private final List<String> users = new ArrayList<>();
15+
16+
@Override
17+
public void handle(HttpExchange exchange) throws IOException {
18+
String method = exchange.getRequestMethod();
19+
switch (method) {
20+
case "GET" -> handleGet(exchange);
21+
case "POST" -> handlePost(exchange);
22+
case "PUT" -> handlePut(exchange);
23+
case "DELETE" -> handleDelete(exchange);
24+
default -> sendResponse(exchange, 405, "Method Not Allowed");
25+
}
26+
}
27+
28+
private void handleGet(HttpExchange exchange) throws IOException {
29+
sendResponse(exchange, 200, users.toString());
30+
}
31+
32+
private void handlePost(HttpExchange exchange) throws IOException {
33+
String newUser = readRequestBody(exchange);
34+
if (!newUser.isBlank()) {
35+
users.add(newUser);
36+
sendResponse(exchange, 201, "User added: " + newUser);
37+
} else {
38+
sendResponse(exchange, 400, "Invalid user data");
39+
}
40+
}
41+
42+
private void handlePut(HttpExchange exchange) throws IOException {
43+
String body = readRequestBody(exchange);
44+
String[] parts = body.split(":", 2);
45+
if (parts.length == 2) {
46+
int index = Integer.parseInt(parts[0]);
47+
String newName = parts[1];
48+
if (index >= 0 && index < users.size()) {
49+
users.set(index, newName);
50+
sendResponse(exchange, 200, "User updated: " + newName);
51+
} else {
52+
sendResponse(exchange, 404, "User not found");
53+
}
54+
} else {
55+
sendResponse(exchange, 400, "Invalid input format");
56+
}
57+
}
58+
59+
private void handleDelete(HttpExchange exchange) throws IOException {
60+
String body = readRequestBody(exchange);
61+
int index;
62+
try {
63+
index = Integer.parseInt(body);
64+
if (index >= 0 && index < users.size()) {
65+
String removedUser = users.remove(index);
66+
sendResponse(exchange, 200, "User deleted: " + removedUser);
67+
} else {
68+
sendResponse(exchange, 404, "User not found");
69+
}
70+
} catch (NumberFormatException e) {
71+
sendResponse(exchange, 400, "Invalid index");
72+
}
73+
}
74+
75+
private void sendResponse(HttpExchange exchange, int statusCode, String response) throws IOException {
76+
exchange.sendResponseHeaders(statusCode, response.length());
77+
OutputStream os = exchange.getResponseBody();
78+
os.write(response.getBytes(StandardCharsets.UTF_8));
79+
os.close();
80+
}
81+
82+
private String readRequestBody(HttpExchange exchange) throws IOException {
83+
InputStream is = exchange.getRequestBody();
84+
return new String(is.readAllBytes(), StandardCharsets.UTF_8);
85+
}
86+
87+
// Helper methods for testing
88+
public List<String> getUsers() {
89+
return new ArrayList<>(users); // Return a copy to prevent external modification
90+
}
91+
92+
public void addUser(String user) {
93+
users.add(user);
94+
}
95+
96+
public void clearUsers() {
97+
users.clear();
98+
}
99+
100+
public static void main(String[] args) throws IOException {
101+
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
102+
server.createContext("/users", new RestApiServer());
103+
server.setExecutor(null);
104+
System.out.println("Server started at http://localhost:8080/users");
105+
server.start();
106+
}
107+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.baeldung.rest;
2+
3+
import com.sun.net.httpserver.HttpExchange;
4+
import org.junit.jupiter.api.BeforeEach;
5+
import org.junit.jupiter.api.Test;
6+
import org.mockito.Mockito;
7+
8+
import java.io.*;
9+
import java.nio.charset.StandardCharsets;
10+
11+
import static org.junit.jupiter.api.Assertions.*;
12+
import static org.mockito.Mockito.*;
13+
14+
class RestApiServerUnitTest {
15+
16+
private RestApiServer restApiServer;
17+
private HttpExchange exchange;
18+
private ByteArrayOutputStream responseStream;
19+
20+
@BeforeEach
21+
void setUp() {
22+
restApiServer = new RestApiServer();
23+
exchange = mock(HttpExchange.class);
24+
responseStream = new ByteArrayOutputStream();
25+
}
26+
27+
private void mockRequest(String method, String body) throws IOException {
28+
InputStream requestBody = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
29+
when(exchange.getRequestMethod()).thenReturn(method);
30+
when(exchange.getRequestBody()).thenReturn(requestBody);
31+
when(exchange.getResponseBody()).thenReturn(responseStream);
32+
when(exchange.getResponseHeaders()).thenReturn(Mockito.mock(com.sun.net.httpserver.Headers.class));
33+
}
34+
35+
@Test
36+
void givenEmptyUserList_whenGetRequest_thenReturnEmptyList() throws IOException {
37+
mockRequest("GET", "");
38+
restApiServer.handle(exchange);
39+
String response = responseStream.toString(StandardCharsets.UTF_8);
40+
assertEquals("[]", response.trim());
41+
}
42+
43+
@Test
44+
void givenValidUser_whenPostRequest_thenUserIsAdded() throws IOException {
45+
mockRequest("POST", "JohnDoe");
46+
restApiServer.handle(exchange);
47+
String response = responseStream.toString(StandardCharsets.UTF_8);
48+
assertTrue(response.contains("User added: JohnDoe"));
49+
}
50+
51+
@Test
52+
void givenEmptyBody_whenPostRequest_thenReturnInvalidUserDataMessage() throws IOException {
53+
mockRequest("POST", "");
54+
restApiServer.handle(exchange);
55+
String response = responseStream.toString(StandardCharsets.UTF_8);
56+
assertTrue(response.contains("Invalid user data"));
57+
}
58+
59+
@Test
60+
void givenValidIndex_whenPutRequest_thenUserIsUpdated() throws IOException {
61+
mockRequest("POST", "JohnDoe");
62+
restApiServer.handle(exchange);
63+
64+
mockRequest("PUT", "0:JaneDoe");
65+
restApiServer.handle(exchange);
66+
String response = responseStream.toString(StandardCharsets.UTF_8);
67+
assertTrue(response.contains("User updated: JaneDoe"));
68+
}
69+
70+
@Test
71+
void givenInvalidIndex_whenPutRequest_thenReturnUserNotFoundMessage() throws IOException {
72+
mockRequest("PUT", "10:NewUser");
73+
restApiServer.handle(exchange);
74+
String response = responseStream.toString(StandardCharsets.UTF_8);
75+
assertTrue(response.contains("User not found"));
76+
}
77+
78+
@Test
79+
void givenValidIndex_whenDeleteRequest_thenUserIsDeleted() throws IOException {
80+
mockRequest("POST", "JohnDoe");
81+
restApiServer.handle(exchange);
82+
83+
mockRequest("DELETE", "0");
84+
restApiServer.handle(exchange);
85+
String response = responseStream.toString(StandardCharsets.UTF_8);
86+
assertTrue(response.contains("User deleted: JohnDoe"));
87+
}
88+
89+
@Test
90+
void givenInvalidIndex_whenDeleteRequest_thenReturnUserNotFoundMessage() throws IOException {
91+
mockRequest("DELETE", "5");
92+
restApiServer.handle(exchange);
93+
String response = responseStream.toString(StandardCharsets.UTF_8);
94+
assertTrue(response.contains("User not found"));
95+
}
96+
}

0 commit comments

Comments
 (0)