티스토리 뷰

RESTful은 REST + WebService 으로 REST 원리를 따르는 시스템 정도로 이해하면 될듯 싶다.

그럼 REST(REpresentational State Transfer)는 무엇일까?

HTTP URI (eg. /customer)로 자원을 표현하고 Method(GET, POST, PUT, DELETE, OPTION, HEAD ...)를 통해 자원에 대한 처리하도록 설계된 아키텍처를 의미한다. 

간단히 사용할수 있고 가볍고 명시적이고 HTTP 프로토콜의 인프라를 사용하므로 별도의 인프라를 구축할 필요도 없다. 이와 같이 수많은 장점을 가지고 있기에 필수적으로 알고 있어야 할 기술이다. 

 

일단 샘플을 구현하기 앞서 REST API 설계부터 진행을 해보자.

JD Method URI
고객의 목록 조회 GET /customer
고객 조회 GET /customer/{custName}
고객 생성 POST /customer
고객 수정 PUT /customer/{custName}
고객 삭제 DELETE /customer/{custName}

이렇게 설계를 마쳤다면 설계를 기반으로 샘플을 작성해 본다. 

 

Customer.Java

public class Customer {
	
	private String custName;
	private String custAddress;
	
	public String getCustName() {
		return custName;
	}
	
	public void setCustName(String custName) {
		this.custName = custName;
	}

	public String getCustAddress() {
		return custAddress;
	}

	public void setCustAddress(String custAddress) {
		this.custAddress = custAddress;
	}
    
    ....
	
}

 

CustomerController.java

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponentsBuilder;

@RestController
public class CustomerController {

	@Autowired
	private CustomerService customerService;
	
	@RequestMapping(value = "/customer", method = RequestMethod.GET) 
	public ResponseEntity<List<Customer>> listAllCustomers() {
		final List<Customer> allCustomers = customerService.findAllCustomers();
		if (allCustomers.isEmpty()) {
			return new ResponseEntity<List<Customer>>(HttpStatus.NO_CONTENT);
		}
		
		return new ResponseEntity<List<Customer>>(allCustomers, HttpStatus.OK);
	}
	
	@RequestMapping(value = "/customer/{custName}", method = RequestMethod.GET)
	public ResponseEntity<Customer> getCustomer(@PathVariable("custName") final int custName) {
		final Customer fetchedCustomer = customerService.findByName(custName);
		if (fetchedCustomer == null) {
			return new ResponseEntity<Customer>(HttpStatus.NOT_FOUND);
		}
		
		return new ResponseEntity<Customer>(fetchedCustomer, HttpStatus.OK);
	}
	
	@RequestMapping(value = "/customer", method = RequestMethod.POST)
	public ResponseEntity<Void> createCustomer(@RequestBody Customer customer, UriComponentsBuilder ucBuilder) {
		
		if (customerService.isCustomerExist(customer)) {
			return new ResponseEntity<Void>(HttpStatus.CONFLICT);
		}
		customerService.saveCustomer(customer);
		
		final HttpHeaders headers = new HttpHeaders();
		headers.setLocation(ucBuilder.path("/customer/{custName}").buildAndExpand(customer.getCustName()).toUri());
		return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
	}
	
	@RequestMapping(value = "/customer/{custName}", method = RequestMethod.PUT)
	public ResponseEntity<Customer> updateCustomer(@PathVariable("custName") final int custName,
			@RequestBody Customer customer) throws Exception {
		
		int count = customerService.updateCustomer(custName, customer);
		
		if (count == 0) {
			return new ResponseEntity<Customer>(HttpStatus.NOT_FOUND);
		}
		
		return new ResponseEntity<Customer>(customer, HttpStatus.OK);
	}
	
	@RequestMapping(value = "/customer/{custName}", method = RequestMethod.DELETE)
	public ResponseEntity<Void> deleteCustomer(@PathVariable("custName") final int custName) {
		Boolean deleteResult = customerService.deleteCustomer(custName);
		
		if (deleteResult == null || !deleteResult) {
			return new ResponseEntity<Void>(HttpStatus.NOT_FOUND);
		}
		
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
}

위의 설계대로 Controller 구현이 완료 되었다. 

Service와 SQL은 기존과 동일하게 작성을 하면 된다. 핵심은 바로 이 Controller이기 때문에 Controller만 이해하면 된다.

@RestController 는 spring 4 부터 지원을 하는 어노테이션으로 Controller 클래스에서 이것만 붙이면 메서드에 @ResponseBody 를 붙이지 않아도 문자열, 객체 등을 리턴할 수 있다. 객체를 리턴하는데 객체는 보통 Json 형태로 변환하여 전달을 하기 때문에 이것을 사용하기 위해서는 jackson library를 추가해서 사용을 해야 한다. 

 

pom.xml

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.5.3</version>
</dependency>

 

위의 Controller는 ResponseEntity를 사용해서 리턴을 해주고 있는데 이는 단순 Value만 리턴하는것이 아닌 상태코드, 응답메세지 등을 같이 보내주기 위한 용도라고 보면 된다. ResponseEntity는 상태코드는 필수로 리턴을 해줘야 한다.  

 

 

또한 요즘은 거의 없겠지만 구형 브라우저를 쓴다면 PUT, DELETE 등의 Method를 지원하지 않는 경우가 있는데 이럴 경우에는 HiddenHttpMethodFilter 를 추가해 줘야 한다. 

 

web.xml

<filter>
	<filter-name>httpMethodFilter</filter-name>
	<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>httpMethodFilter</filter-name>
	<url-pattern>/</url-pattern>
</filter-mapping> 

 

댓글
최근에 올라온 글
최근에 달린 댓글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31