REST

cy8erpsycho·2023년 9월 4일
0

스프링

목록 보기
23/29
post-thumbnail

URL / URI

URI

URI의 약자는 Uniform Resource Identifier이며 자원의 식별자라는 뜻을 가지고 있습니다. 즉, 인터넷 상에서 어떤 자원을 식별하기 위한 문자열의 구성이라고 말할 수 있으며 이는 URL과 URN의 상위 개념으로서 이들을 포함하고 있다.

URL과 URN은 URI에 포함되는 관계이며 이 둘의 차이는 자원을 식별하는 방식이 다르다는 것이다. 즉 다시 한번 정리하자면 URL과 URN은 URI의 하위 개념이며 자원을 식별하는 목적은 같으나 서로의 식별 방식이 다르다고 할 수 있다.

URI는 URL과 URN의 상위 개념이기에 평소에 주변에서 흔히 보던 문자열의 주소가 대부분 URI에 포함될 것이다.

URI 예시 (1)
http://www.school.com/grade/2

URI 예시 (2)
http://www.school.com/student?name=아무개


URL

URI의 하위 개념 중 첫 번째 URL의 약자는 Uniform Resource Locator이며 자원의 위치라는 뜻을 가지고 있다. 즉, 인터넷 상에서 어떤 자원을 식별할 때 자원의 위치를 활용하여 특정 자원을 식별하겠다는 것이다.

URL 예시 (1)
http://www.school.com/grade/2

URL 예시 (2)
http://www.school.com/student?name=아무개

위 예시의 특정 문자열 주소에서 URL은 위에서 보았던 URI와는 달리 포함 범위가 조금 더 짧은 모습을 볼 수 있다. 예시 1의 경우 grade 다음에 나오는 숫자에 따라 특정 자원의 결과가 다르게 나올 수 있기 때문에 이는 자원의 위치의 역할을 하는 URL보다는 자원의 식별자 역할을 하는 URI와 더욱 적합하기에 숫자 값 이전의 grade까지가 문자열 주소에서의 URL이라고 할 수 있는 것이다.

위와 동일한 방식의 예시 2의 경우에도 student 다음에 나오는 쿼리 문인 name 값에 따라 특정 자원의 결과가 다르게 도출될 수 있기 때문에 이는 자원의 위치 역할을 한다기보다는 URI와 같이 자원의 식별자 역할을 하므로 name 이전까지가 URL인 것이다.

URL은 URI에서 데이터 부분을 제외한 부분을 의미한다.
예시(1)은 RestController에서 파라미터를 예시(2)는 get방식의 쿼리스트링을 의미한다.

결론

URL과 URI에서 "위치를 나타낸다"와 "식별한다"라는 표현의 차이는 다음과 같습니다.

URL (Uniform Resource Locator)

URL은 "Locator"라는 단어에서도 알 수 있듯이, 리소스가 어디에 "위치"하고 있는지 나타냅니다. 이는 다시 말해, 해당 리소스를 어떻게 접근해야 하는지에 대한 구체적인 방법을 제공합니다.

예: http://www.example.com/folder/file.html

  • http는 프로토콜을 나타냅니다.
  • www.example.com은 서버의 도메인을 나타냅니다.
  • /folder/file.html은 서버상의 파일 경로를 나타냅니다.

이러한 정보들을 통해, http://www.example.com/folder/file.html라는 URL은 "www.example.com"이라는 서버에서 어떤 프로토콜을 사용해 (http), 어떤 경로의 (/folder/file.html) 리소스를 얻을 수 있는지를 구체적으로 나타냅니다.

URI (Uniform Resource Identifier)

URI는 "Identifier"라는 단어에서도 알 수 있듯이, 리소스를 "식별"하기만 하면 됩니다. 이는 위치 정보를 포함할 수도, 포함하지 않을 수도 있습니다. 즉, URI는 리소스가 무엇인지만을 나타내며, 그 리소스를 어떻게 얻을 수 있는지에 대한 정보는 필수적이지 않습니다.

예:

  • URL 형태의 URI: http://www.example.com/folder/file.html
  • URN 형태의 URI: urn:isbn:0451450523

차이점

  • URL은 리소스의 "위치"와 "접근 방법"까지 명시적으로 나타냅니다.
  • URI는 리소스를 "식별"만 합니다. 이는 URL을 포함할 수도 있고, URN과 같이 위치를 나타내지 않을 수도 있습니다.

즉, 모든 URL은 그 자체로 URI입니다(위치를 통해 식별하기 때문에). 하지만 모든 URI가 URL은 아닙니다(식별만 할 수 있고 위치를 나타내지 않을 수 있기 때문에).



@RestController

REST 방식에서는 서버에서 전송하는 것이 순수한 데이터라는 것을 기억해야 한다.

@RestConteroller는 메소드의 리턴 타입으로 사용자가 정의한 클래스 타입을 사용할 수 있고, 이를 XML이나 JSON으로 처리한다.

예제 프로젝트의 준비

  1. ex03 프로젝트 생성
  2. context path '/'루트로 바꾸기
  3. 인코딩 필터 추가하기
  4. 롬복 1.18.24버전으로 변경
  5. pom.xml에 추가해야 할 것들
  • mybatis 추가
  • ojdbc 추가
  • spring-jdbc 추가
  • spring-test 추가
  • jackson-databind 추가
  • jackson-dataformat 추가
  • gson 추가

jackspn-databind

jackson-databind 라이브러리는 나중에 브라우저에 객체를 JSON이라는 포맷의 문자열로 변환시켜 전송할때 필요하다.

https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind/2.14.2

pom.xml에 등록하고

제대로 등록되었는지 한번 더 확인한다.

jackspn-dataformat

https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml/2.14.2

compile dependency에 있는 woodstox-core와 stax-2는 dataformat을 설치하면 자동으로 설치된다.

Gson

테스트할 때 직접 JAVA 인스턴스를 JSON 타입의 문자열로 변환해야 하는 일들도 있으므로 gson 라이브러리를 추가한다.

https://mvnrepository.com/artifact/com.google.code.gson/gson/2.8.9

gson은 compiledependency가 없다.

lombok

메이븐에서 <dependency> 를 추가하는 것과 별개로 위의 경로에서롬복을 더블클릭해서 직접 sts 업데이트 해야한다.

STS 폴더내의 STS.ini 파일에 위와 같이 적용이 되어야 한다.

현재시간으로 업데이트 된것을 볼 수 있다.



@RestController의 반환 타입

단순 문자열 반환

@RestController는 JSP와 달리 순수한 데이터를 반환하는 형태이므로 다양한 포맷의 데이터를 전송할 수 있다.

SampleController.java

produces 속성 : 해당 메서드가 생산하는 MIME 타입을 의미한다. produces="text/plain" 텍스트인데 단순 텍스트이다라는 뜻이다.
위와 같이 문자열로 직접 지정할 수도 있고, 메서드 내의 MediaType이라는 클래스를 이용할 수도 있다.

기존의 @Controller는 문자열을 반환하는 경우에는 JSP 파일의 이름으로 처리하지만, @RestController의 경우에는 순수한 데이터가 된다.


객체의 반환

객체를 반환하는 작업은 JSON이나 XML을 이용한다.

SampleVO.java

SampleController.java

컨트롤러에 객체를 리턴하는 메소드를 추가한다.

xml 형태로 전송된것을 볼 수 있다.(produce의 디폴트값)

json으로 전달하기 위해선 어떻게 해야할까?

위와 같이 작성하면 json형태로 전송한다는 뜻이다. 아래와 같은 화면을 확인할수 있다.


또 다음과 같이 작성할 수도 있다.

위와 같이 작성하면 XML과 JSON을 두개다 지원한다는 뜻이다.
요청할때 .json을 붙여서 요청을 하면 화면상에 json의 데이터가 나오는 것을 확인 할수 있다. default는 xml으로 출력된다.

@GetMapping이나 @RequestMapping의 produces 속성은 반드시 지정해야 하는 것은 아니므로 생략하는 것도 가능하다(똑같이 나온다.)


컬렉션 타입의 객체 반환

배열은 어떤식으로 리턴할까?

List

바깥쪽이 list인것으로 collection임을 알수있다. 컬렉션안쪽에 여러개의 아이템이 담겨서 돌아온다.

[{"mno":1,"firstName":"first1","lastName":"last1"},
 {"mno":2,"firstName":"first2","lastName":"last2"},
 {"mno":3,"firstName":"first3","lastName":"last3"},
 {"mno":4,"firstName":"first4","lastName":"last4"},
 {"mno":5,"firstName":"first5","lastName":"last5"},
 {"mno":6,"firstName":"first6","lastName":"last6"},
 {"mno":7,"firstName":"first7","lastName":"last7"},
 {"mno":8,"firstName":"first8","lastName":"last8"},
 {"mno":9,"firstName":"first9","lastName":"last9"}]

json으로 응답받을때는 json array형태로 돌아온다 {}는 객체를 뜻하고 [] 은 배열을 뜻한다.


Map

데이터를 돌려줄수 있는 restapi에서 객체를 돌려줄때 json이나 xml로 변화시켜 전송할수있다. 데이터를 돌려줄떄 문자열로 줄 수 있는점.


ResponseEntity 타입

REST 방식으로 호출되는 경우는 화면 자체가 아니라 데이터 자체를 전송하는 방식으로 처리되기 때문에 데이터를 요청한 쪽에서는 정상적인 데이터인지 비정상적인 데이터인지를 구분할 수 있는 확실한 방법을 제공해야 한다.

ResponseEntity는 데이터와 함께 HTTP 헤더의 상태 메세지 등을 같이 전달하는 용도로 사용한다.

기본적인 틀을 아래와 같이 작성한다.

	@GetMapping(value="/check")
	public ResponseEntity<SampleVO> check(){
		return null;
	}

헤더를 처리한다?(HttpStatus)


BAD_GATEWAY를 OK로 고치면 헤더의 응답이 200 ok로 바뀌는 것을 볼 수 있다.

정리

헤더의 Status code를 설정할수 있다.

일반 문자열은 그냥 전달된다.

객체를 돌려줄땐 문자열화 되서 전달된다.(제이슨 , xml)

배열의 형태는 map이나 list등 잘 형태가 변환되서 전달된다.

ResponseEntity를 이용해서 데이터를 조작해서 보낼 수 있다.



@RestController의 파라미터

위와 같은 형태가 쿼리스트링 형태

REST API에서는 대신 디렉토리 형태 즉, path의 형태로 요청을 한다.

메소드가 어떻게 매핑되는지가 가장 핵심이다.

인자매핑을 지정을 해줘야함.

@PathVariable("cat") 이렇게 인자를 매핑해줘야한다.

	@GetMapping(value="/product/{cat}/{pid}") // 이거 이용해서 웹툰 경로를 설정하면될거같은데
	public String[] getPath(@PathVariable("cat") String cat, @PathVariable("pid") Integer pid) {
		String[] arr = new String[] {"category : " + cat, "productId : " + pid };
		return arr;
	}


객체생성해서 파라미터를 객체로 받고 싶다. 어떻게 하지

티켓클래스 생성

  • @RequestBody: JSON 데이터를 원하는 타입의 객체로 변환

첫번째 줄은 리퀘스트 명령줄
그다음이 리퀘스트 헤더
get방식은 request바디가없다

post방식
request 바디에 pageNum=1&amount= 10이 들어간다

그런데 위와 같은 포스트 방식은 어떻게 테스트를 하지?

포스트맨에서 JSON형태로 보내서 확인할 수 있다.

메소드의 형식에 따라 DB의 CRUD와 매핑시킬수있다.

0개의 댓글