07 - User API แบบไม่ใช้ฐานข้อมูล
เป้าหมายของบท
Section titled “เป้าหมายของบท”บทนี้จะสร้าง User API แบบง่ายโดยใช้ List<User> เก็บข้อมูลใน memory ก่อน จุดประสงค์คือให้เข้าใจ controller, path variable, request body และ response ก่อนเข้าสู่ database จริง
หลังจบบทนี้จะได้ endpoint:
GET /api/v1/usersGET /api/v1/users/{id}POST /api/v1/usersDELETE /api/v1/users/{id}ทำไมต้องเริ่มแบบไม่ใช้ database
Section titled “ทำไมต้องเริ่มแบบไม่ใช้ database”มือใหม่มักเจอปัญหาหลายอย่างพร้อมกัน เช่น controller ไม่ทำงาน, JSON ไม่ถูก, database ต่อไม่ได้, table ไม่ถูกสร้าง ถ้าเริ่มทุกอย่างพร้อมกันจะ debug ยาก
บทนี้จึงตัด database ออกก่อน แล้วโฟกัสที่ REST API flow:
Postman -> UserController -> List<User> -> Responseสร้าง User model
Section titled “สร้าง User model”สร้างไฟล์:
src/main/java/com/example/backendapi/model/User.javapackage com.example.backendapi.model;
import lombok.Getter;import lombok.Setter;
@Getter@Setterpublic class User { private Long id; private String username; private String email;}ตอนนี้ User ยังไม่ใช่ Entity เพราะยังไม่ใช้ JPA และ database
สร้าง UserController
Section titled “สร้าง UserController”สร้างไฟล์:
src/main/java/com/example/backendapi/controller/UserController.javapackage com.example.backendapi.controller;
import com.example.backendapi.model.User;import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;import java.util.List;
@RestController@RequestMapping("/api/v1/users")public class UserController {
private final List<User> users = new ArrayList<>(); private Long nextId = 1L;
@GetMapping public List<User> getUsers() { return users; }
@GetMapping("/{id}") public User getUser(@PathVariable Long id) { return users.stream() .filter(user -> user.getId().equals(id)) .findFirst() .orElseThrow(() -> new RuntimeException("User not found")); }
@PostMapping public User createUser(@RequestBody User user) { user.setId(nextId++); users.add(user); return user; }
@DeleteMapping("/{id}") public String deleteUser(@PathVariable Long id) { User user = getUser(id); users.remove(user); return "User deleted"; }}ทดสอบสร้าง user
Section titled “ทดสอบสร้าง user”เรียก:
POST http://localhost:8080/api/v1/usersBody:
{ "username": "john", "email": "john@example.com"}Expected response:
{ "id": 1, "username": "john", "email": "john@example.com"}ทดสอบอ่านรายชื่อ user
Section titled “ทดสอบอ่านรายชื่อ user”GET http://localhost:8080/api/v1/usersExpected response:
[ { "id": 1, "username": "john", "email": "john@example.com" }]ทดสอบอ่าน user ตาม id
Section titled “ทดสอบอ่าน user ตาม id”GET http://localhost:8080/api/v1/users/1ข้อจำกัดของ in-memory API
Section titled “ข้อจำกัดของ in-memory API”โค้ดนี้ยังไม่เหมาะกับ production:
- ข้อมูลหายเมื่อ restart application
- ยังไม่มี validation
- ยังตอบ error เป็น 500 เมื่อ user not found
- ยังไม่ได้แยก service
- thread-safety ยังไม่ใช่ประเด็นที่จัดการ
ทั้งหมดนี้เราจะค่อย ๆ แก้ในบทถัดไปและภาคถัด ๆ ไป
Checkpoint
Section titled “Checkpoint”บทนี้ถือว่าสำเร็จเมื่อ:
POST /api/v1/usersสร้าง user ได้GET /api/v1/usersเห็น user ที่สร้างGET /api/v1/users/1อ่าน user id 1 ได้DELETE /api/v1/users/1ลบ user ได้
แบบฝึกหัดท้ายบท
Section titled “แบบฝึกหัดท้ายบท”เพิ่ม endpoint:
PUT /api/v1/users/{id}เพื่อแก้ไข username และ email