오늘은 RESTful API 기반으로 사용자 목록 조회를 위한 API 구현을 해보겠습니다.
먼저 간단하게 개념에 대해 알아보고 코드 진행 해보겠습니다.
RESTful API 란?
RESTful API은 Representational State Transfer API 약자로, 웹 서비스 디자인 아키텍처 중 하나로, 네트워크 아키텍처 원칙인 REST를 따르는 웹 API를 의미합니다. REST는 Roy Fielding이 2000년에 제안한 웹 아키텍처 스타일로, 웹의 기본 원칙을 따르며 간결하고 확장 가능한 시스템을 구축하기 위해 사용됩니다.
RESTful API는 다음과 같은 특징이 있습니다.
- 자원 지향 (Resource-Oriented): RESTful API는 리소스(Resource)를 중심으로 설계됩니다. 리소스는 웹 상의 모든 것을 의미할 수 있으며, 예를 들어 사용자, 블로그 게시물, 주문 등이 리소스가 될 수 있습니다.
- HTTP 메서드 활용: RESTful API는 HTTP 메서드를 사용하여 리소스를 다룹니다. 가장 흔히 사용되는 HTTP 메서드는 다음과 같습니다.
- GET: 리소스를 조회하기 위해 사용합니다.
- POST: 리소스를 생성하기 위해 사용합니다.
- PUT: 리소스를 수정하기 위해 사용합니다.
- DELETE: 리소스를 삭제하기 위해 사용합니다.
- 상태 없음 (Statelessness): RESTful API는 서버가 클라이언트의 상태를 유지하지 않습니다. 각 요청은 클라이언트의 모든 정보를 포함하고 있어야 하며, 서버는 이 정보만을 기반으로 요청을 처리합니다.
- 자체 표현 (Self-Descriptive): RESTful API는 리소스에 대한 정보를 포함한 자체 표현 메시지를 사용합니다. 예를 들어 JSON 또는 XML 형식의 데이터를 리소스의 표현으로 사용합니다.
- 하이퍼미디어 (Hypermedia): RESTful API는 하이퍼미디어를 통해 클라이언트가 API를 사용하도록 유도합니다. 하이퍼미디어는 링크를 포함하여 리소스 간의 관계와 API 상태 전이를 나타냅니다.
정리하자면 웹 브라우저를 포함한 다양한 클라이언트에서 쉽게 사용하고 확장할 수 있으며, HTTp 프로토콜을 기반으로 동작하기 때문에 네트워크 상에서 캐싱, 로드 밸런싱 등의 기술을 활용할 수 있습니다. 이러한 특징들로 인해 RESTful API는 현대적인 웹 서비스의 주요 아키텍처 중 하나로 많이 사용되고 있습니다.
개념은 여기까지 정리하기로 하고 다음으로 사용자 목록 조회를 위한 코드로 알아봅시다.
GET HTTP Method
먼저 코드를 확인해 보자.
@RestController
public class UserController {
private UserDaoService service;
public UserController(UserDaoService service){
this.service = service;
}
@GetMapping("/users")
public List<User> retrieveAllUsers(){
return service.findAll(); // 전체 사용자 목록
}
// GET/users/1 or / users/10 -> String
@GetMapping("/users/{id}")
public EntityModel<User> retrieveUser(@PathVariable int id){ // 자동으로 int로 처리됨
User user = service.findOne(id);
if(user == null){
throw new UserNotFoundException(String.format("ID[%s] not found",id));
}
//EntityModel의 생성자는 protected로 되어 있어 바로 사용할 수 없다.
//EntityModel을 새로 생성하는게 아닌, of 메서드를 사용해서 연결해줘야한다.
//HATEOAS
EntityModel<User> model = EntityModel.of(user);
WebMvcLinkBuilder linkTo = linkTo(methodOn(this.getClass()).retrieveAllUsers());
model.add(linkTo.withRel("all-users"));
return model;
}
위 코드는 RESTful API 기반으로 전체 사용자 목록/ 개별 사용자 목록 조회 GET Mapping 코드입니다.
이전 포스팅에서 EntityModel 메서드에 대해 알아봤기 때문에 개념은 생략하겠습니다.
(알아보고 계신 분들은 아래 포스팅을 참고해 보시면 도움이 되실 거 같습니다!)
그럼 첫 줄부터 알아보자면,
RESTful API 기반으로 진행할 때 사용되는 @RestController 어노테이션을 사용했는데, Spring Frame Work/ Boot를 활용해서 프로젝트 및 공부하고 계신 분들이라면 @(어노테이션)을 사용해서 @Controller를 사용해 보셨을 거예요.
@RestController는 스프링 프레임워크에서 제공하는 어노테이션 중 하나로, 웹 애플리케이션에서 RESTful 웹 서비스를 구현하는 데 사용됩니다. 즉, 어노테이션이 클래스 레벨에 적용되면 해당 클래스는 REST 컨트롤러로 동작하게 되는데,
일반적으로 스프링 컨트롤러 클래스에 @Controller 어노테이션을 사용하여 웹 요청을 처리하고, @ResponseBody 어노테이션을 추가하여 메서드가 HTTP 응답 본문에 데이터를 직접 쓰도록 설정할 수 있습니다. 이러한 방식은 JSON, XML 등과 같은 데이터를 반환하는 RESTful API를 구현하는 데 유용합니다.
private UserDaoService service;
public UserController(UserDaoService service) {
...
}
다음으로는 UserDaoService 타입의 Service 멤버 변수를 선언했는데, 이 변수는 사용자 데이터에 접근하는 데 사용됩니다.
저는 생성자를 생성해서 접근했는데,
@Autowired
private UserDaoService service;
@Autowired 어노테이션을 사용해서 DI 주입을 하셔도 됩니다.
의존성 주입을 했다면 이제 GET 요청을 처리하는 메서드를 생성하기 위해 @GetMapping 메서드를 사용해서 경로를 지정해 줍니다. 위 코드의 경로는 '/users' / '/users/{id}'로 GET요청을 처리합니다.
전체 사용자는 들어오는 값이 없이 경로만 지정했고, 해당 유저 조회는 id 값을 매게 변수로 바인딩합니다.
@GetMapping("/users")
public List<User> retrieveAllUsers(){
return service.findAll(); // 전체 사용자 목록
}
// GET/users/1 or / users/10 -> String
@GetMapping("/users/{id}")
public EntityModel<User> retrieveUser(@PathVariable int id){ // 자동으로 int로 처리됨
User user = service.findOne(id);
다음으로는 EntityModel <User> 메서드 시그니처 선언부에 대한 부분인데, 이 부분은 위 포스팅 글에 더 자세하게 다뤘기 때문에 생략하겠습니다.
그렇다면 다음으로 경로를 확인해야 하는 부분은 바로 findAll(); / findOne(id) 일 텐데, 두 메서드는 service를 통해 사용자 정보를 조회합니다.
예시 코드르는 데이터베이스를 대체하여 사용자 정보를 관리하는 기능을 제공하는 서비스 클래스를 생성합니다.
@Service
public class UserDaoService {
private static List<User> users = new ArrayList<>();
private static int usersCount = 3;
static { // data 3개
users.add(new User(1,"Kenneth",new Date(),"pass1","701010-1111111"));
users.add(new User(2,"Alice",new Date(),"pass2","701010-2222222"));
users.add(new User(3,"Elena",new Date(),"pass3","701010-3333333"));
}
// service 클래스 생성
public List<User> findAll(){
return users;
}
public User save(User user){
if (user.getId() == null){
user.setId(++usersCount);
}
users.add(user);
return user;
}
public User findOne(int id){
for (User user : users){
if(user.getId() == id){
return user;
}
}
return null;
}
먼저 ArrayList <>()를 생성해서 사용자 정보를 저장할 리스트인 'users'를 정적 변수로 선언합니다.
다음으로는 사용자 ID를 자동으로 생성하기 위한 정적 변수 'usersCount'를 선언하는데, 초기값으로 '3'을 할당해 주고, 임의로 데이터를 주입하기 위해 정적 초기화 블록을 생성해 줍니다.
static { // data 3개
users.add(new User(1,"Kenneth",new Date(),"pass1","701010-1111111"));
users.add(new User(2,"Alice",new Date(),"pass2","701010-2222222"));
users.add(new User(3,"Elena",new Date(),"pass3","701010-3333333"));
}
클래스가 로딩될 때 실행되며, 사용자 정보를 초기화하여 'users' 리스트에 추가합니다. 여기서는 총 3명의 사용자 데이터를 초기화합니다.
오늘은 GET Method에 대해 알아보기 위한 포스팅으로 save()는 생략하겠습니다.
findAll() / findOne 메서드 코드에는 각각의 return 값을 반환해 주는데, findOne(id) 메서드는 주어진 ID에 해당하는 사용자를 조회해서 ID와 일치하는 사용자를 찾아 반환해 줍니다. 만약 일치하지 않다면 null을 반환합니다.
다음으로 결과를 알아보겠습니다.
확인을 위해 PostMan을 활용하겠습니다.
[ 전체 사용자 목록 조회 ]
[ 사용자 상세 정보 ]
마치며
오늘은 사용자 목록 조회를 위한 RESTful API 구현에 대해 알아봤습니다.
다음 포스팅에서 뵙겠습니다.
'[ JAVA ] > JAVA RESTful API' 카테고리의 다른 글
[ RESTful API ] SimpleBeanPropertyFilter (0) | 2023.08.04 |
---|---|
[ RESTful API ] JPA 연동 - 사용자 CRUD 기능 구현 (0) | 2023.08.02 |
[ RESTful API ] 사용자 수정/삭제를 위한 API 구현 - PUT/DELETE HTTP Method (0) | 2023.07.28 |
[ RESTful API ] 사용자 등록을 위한 API 구현 - POST HTTP Method (0) | 2023.07.27 |
[ RESTful API ] EntityModel 개념 및 예제 (0) | 2023.07.24 |