Skip to content

29 - Admin ดูรายชื่อผู้ใช้

บทนี้จะสร้าง endpoint สำหรับ admin ดูรายชื่อผู้ใช้ทั้งหมด:

GET /api/v1/admin/users

หลังจบบทนี้ผู้อ่านควรเข้าใจ:

  • admin user list ต่างจาก user list ปกติอย่างไร
  • ทำไมต้องมี pagination
  • filter ด้วย status/role/keyword ได้อย่างไร
  • response ควรใช้ PageResponse<UserResponse>
  • endpoint นี้ต้องถูกป้องกันด้วย role ADMIN
GET /api/v1/admin/users?page=0&size=20&status=ACTIVE&role=USER&keyword=john

parameter:

Parameterความหมาย
pageหน้า เริ่มจาก 0
sizeจำนวนรายการต่อหน้า
statusACTIVE หรือ INACTIVE
roleUSER หรือ ADMIN
keywordค้นจาก username/email

เพิ่ม method ใน UserRepository

Section titled “เพิ่ม method ใน UserRepository”

เพิ่ม method ใหม่เข้าไปใน UserRepository เดิมจากบทก่อนหน้า อย่าลบ method search ของ user list ปกติจากบท 20 เพราะ UserService ยังใช้อยู่:

Page<User> findByUsernameContainingIgnoreCaseOrEmailContainingIgnoreCase(
String username,
String email,
Pageable pageable
);
@Query("""
select u from User u
where (:status is null or u.status = :status)
and (:role is null or u.role = :role)
and (
:keyword = ''
or lower(u.username) like lower(concat('%', :keyword, '%'))
or lower(u.email) like lower(concat('%', :keyword, '%'))
)
""")
Page<User> searchForAdmin(
UserStatus status,
Role role,
String keyword,
Pageable pageable
);

import:

import com.example.backendapi.model.Role;
import com.example.backendapi.model.UserStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;

สร้างไฟล์:

src/main/java/com/example/backendapi/service/AdminUserService.java
package com.example.backendapi.service;
import com.example.backendapi.common.PageResponse;
import com.example.backendapi.dto.UserResponse;
import com.example.backendapi.model.Role;
import com.example.backendapi.model.User;
import com.example.backendapi.model.UserStatus;
import com.example.backendapi.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class AdminUserService {
private final UserRepository userRepository;
public PageResponse<UserResponse> findUsers(
int page,
int size,
UserStatus status,
Role role,
String keyword
) {
int safeSize = Math.min(size, 100);
Pageable pageable = PageRequest.of(
page,
safeSize,
Sort.by("createdAt").descending()
);
return PageResponse.from(
userRepository.searchForAdmin(status, role, normalize(keyword), pageable)
.map(this::toResponse)
);
}
private String normalize(String keyword) {
if (keyword == null || keyword.isBlank()) {
return "";
}
return keyword.trim();
}
private UserResponse toResponse(User user) {
return new UserResponse(
user.getId(),
user.getUsername(),
user.getEmail(),
user.getRole(),
user.getStatus(),
user.getCreatedAt(),
user.getUpdatedAt()
);
}
}

สร้างไฟล์:

src/main/java/com/example/backendapi/controller/AdminUserController.java
package com.example.backendapi.controller;
import com.example.backendapi.common.ApiResponse;
import com.example.backendapi.common.PageResponse;
import com.example.backendapi.dto.UserResponse;
import com.example.backendapi.model.Role;
import com.example.backendapi.model.UserStatus;
import com.example.backendapi.service.AdminUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/v1/admin/users")
@RequiredArgsConstructor
public class AdminUserController {
private final AdminUserService adminUserService;
@GetMapping
public ApiResponse<PageResponse<UserResponse>> findUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size,
@RequestParam(required = false) UserStatus status,
@RequestParam(required = false) Role role,
@RequestParam(required = false) String keyword
) {
return ApiResponse.ok(
"Users found",
adminUserService.findUsers(page, size, status, role, keyword)
);
}
}
{
"success": true,
"message": "Users found",
"data": {
"content": [
{
"id": 1,
"username": "john",
"email": "john@example.com",
"role": "USER",
"status": "ACTIVE"
}
],
"page": 0,
"size": 20,
"totalElements": 1,
"totalPages": 1,
"first": true,
"last": true
}
}

แบบฝึกหัดท้ายบท

Section titled “แบบฝึกหัดท้ายบท”
  1. เพิ่ม searchForAdmin ใน UserRepository
  2. สร้าง AdminUserService
  3. สร้าง AdminUserController
  4. ทดสอบ filter ด้วย status=ACTIVE
  5. ทดสอบ filter ด้วย role=ADMIN
  6. ทดสอบ keyword ที่ค้นจาก email