반응형
이번에는 RESTful API 설계 원칙에 따라 API를 설계하고, 대량의 데이터를 효율적으로 다룰 수 있도록 페이징(Pagination) 기능을 구현하는 방법을 알아보겠습니다.
1. RESTful API 설계 원칙
RESTful API는 웹에서 자원을 구조적으로 접근할 수 있도록 설계된 API입니다. 다음과 같은 설계 원칙을 따릅니다:
- 자원(Resource): API는 URL을 통해 자원을 표현합니다.
예: /users, /users/{id} - HTTP 메서드:
- GET: 자원 조회
- POST: 자원 생성
- PUT: 자원 업데이트
- DELETE: 자원 삭제
- 표현(Representation): JSON 또는 XML 형식으로 데이터를 반환합니다.
- 무상태성(Statelessness): API 호출 간 상태를 서버에 저장하지 않습니다.
2. RESTful API 페이징의 필요성
대량의 데이터를 한 번에 반환하면 네트워크 성능 및 응답 시간이 저하될 수 있습니다.
페이징을 구현하면 데이터를 페이지 단위로 나누어 반환할 수 있어 효율적인 데이터 전송이 가능합니다.
3. API 설계 예시: 사용자 목록 조회
- URL: /api/users
- HTTP 메서드: GET
- 쿼리 파라미터:
- page: 요청 페이지 번호 (기본값: 1)
- size: 페이지 크기 (기본값: 10)
응답 예시:
{
"page": 1,
"size": 10,
"totalPages": 5,
"totalElements": 50,
"data": [
{"id": 1, "name": "User 1", "email": "user1@example.com"},
{"id": 2, "name": "User 2", "email": "user2@example.com"},
...
]
}
4. Pagination 구현: Controller, Service, DAO
Controller 코드
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public ResponseEntity<?> getUsers(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
return ResponseEntity.ok(userService.getUsers(page, size));
}
}
Service 코드
@Service
public class UserService {
@Autowired
private UserDao userDao;
public Map<String, Object> getUsers(int page, int size) {
int offset = (page - 1) * size;
List<User> users = userDao.fetchUsers(offset, size);
int totalElements = userDao.countUsers();
int totalPages = (int) Math.ceil((double) totalElements / size);
Map<String, Object> response = new HashMap<>();
response.put("page", page);
response.put("size", size);
response.put("totalPages", totalPages);
response.put("totalElements", totalElements);
response.put("data", users);
return response;
}
}
DAO 코드
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<User> fetchUsers(int offset, int size) {
String sql = "SELECT * FROM users ORDER BY id LIMIT ? OFFSET ?";
return jdbcTemplate.query(sql, new Object[]{size, offset}, new UserRowMapper());
}
public int countUsers() {
String sql = "SELECT COUNT(*) FROM users";
return jdbcTemplate.queryForObject(sql, Integer.class);
}
}
UserRowMapper
public class UserRowMapper implements RowMapper<User> {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setEmail(rs.getString("email"));
return user;
}
}
5. 테스트 결과
API 호출 예:
GET /api/users?page=2&size=5
결과:
{
"page": 2,
"size": 5,
"totalPages": 10,
"totalElements": 50,
"data": [
{"id": 6, "name": "User 6", "email": "user6@example.com"},
{"id": 7, "name": "User 7", "email": "user7@example.com"},
...
]
}
6. 페이징 구현 시 고려사항
- 대용량 데이터 처리 최적화
- 적절한 인덱스 설정.
- 필요한 컬럼만 조회.
- 응답 속도 최적화
- 페이지 크기를 제한하여 대규모 데이터를 반환하지 않도록 설정.
- 에러 처리
- 페이지 범위를 벗어난 요청에 대한 처리.
- 잘못된 쿼리 파라미터에 대한 검증.
반응형
'개발 > 전자정부프레임워크' 카테고리의 다른 글
RESTful API에 인증과 권한 관리 추가하기 (0) | 2025.01.03 |
---|---|
파일 업로드와 다운로드 기능 구현 (1) | 2025.01.03 |
JDBC 배치 처리와 성능 최적화 (0) | 2025.01.02 |
JDBC를 사용한 트랜잭션 처리 심화 학습 (0) | 2025.01.02 |
MyBatis 캐싱(Cache) 사용하기 (0) | 2025.01.02 |