개요

HTTP 동사

본 REST API에서 사용하는 HTTP 동사(verbs)는 가능한한 표준 HTTP와 REST 규약을 따릅니다.

동사 용례

GET

리소스를 가져올 때 사용

POST

새 리소스를 만들 때 사용

PUT

기존 리소스를 수정할 때 사용

PATCH

기존 리소스의 일부를 수정할 때 사용

DELETE

기존 리소스를 삭제할 떄 사용

HTTP 상태 코드

본 REST API에서 사용하는 HTTP 상태 코드는 가능한한 표준 HTTP와 REST 규약을 따릅니다.

상태 코드 용례

200 OK

요청을 성공적으로 처리함

201 Created

새 리소스를 성공적으로 생성함. 응답의 Location 헤더에 해당 리소스의 URI가 담겨있다.

204 No Content

기존 리소스를 성공적으로 수정함.

400 Bad Request

잘못된 요청을 보낸 경우. 응답 본문에 더 오류에 대한 정보가 담겨있다.

404 Not Found

요청한 리소스가 없음.

오류

에러 응답이 발생했을 때 (상태 코드 >= 400), 본문에 해당 문제를 기술한 JSON 객체가 담겨있다.

Auth Error

Error0001

Response body
{
  "timestamp" : "2021-02-06T10:20:21.7024383",
  "status" : 202,
  "error" : "0001",
  "message" : "ID: TestUser1 이미 사용중인 아이디입니다."
}

Error0002

Response body
{
  "timestamp" : "2021-02-06T10:20:20.1984677",
  "status" : 403,
  "error" : "0002",
  "message" : "ID: TestUser1 회원가입이 되어있지 않거나 잠긴 계정입니다."
}

Error0005

Response body
{
  "timestamp" : "2021-02-06T10:20:18.5203357",
  "status" : 403,
  "error" : "0005",
  "message" : "잘못된 인증입니다."
}

System Error

Error2001

Response body

Snippet response-body not found for operation::2001

하이퍼미디어

본 REST API는 하이퍼미디어와 사용하며 응답에 담겨있는 리소스는 다른 리소스에 대한 링크를 가지고 있다. 응답은 Hypertext Application from resource to resource. Language (HAL) 형식을 따른다. 링크는 `_links`라는 키로 제공한다. 본 API의 사용자(클라이언트)는 URI를 직접 생성하지 않아야 하며, 리소스에서 제공하는 링크를 사용해야 한다.

인증

JWT인증은 표준을 따른다. Authorization 헤더에 Bearer + 공백 + JWT 토큰값 을 보내주어야 한다.

인증하기

Post 요청을 사용해서 인증할수있다.

HTTP request

POST /auth/signin HTTP/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 79
Host: templet.restapi.com

{
  "id" : "TestUser1",
  "password" : "password",
  "role" : "ROLE_USER"
}

Example response

HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
Content-Length: 253

{
  "accessToken" : "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJUZXN0VXNlcjEiLCJyb2xlcyI6WyJST0xFX1VTRVIiXSwiaWF0IjoxNjEyNTc0NDIwfQ.4wehBPFLcxgz_4sT9d0VuBKDyEG8dSxO0EtX6k4T2NY",
  "id" : "TestUser1",
  "name" : "테스트 유저 1",
  "storeName" : null
}

회원가입하기(회원)

Post 요청을 사용해서 회원가입을 할 수있다.

HTTP request

POST /auth/signup HTTP/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 275
Host: templet.restapi.com

{
  "id" : "TestUser1",
  "password" : "Password",
  "name" : "테스트 유저 1",
  "phoneNumber" : "전화번호~",
  "address" : "집주소",
  "role" : "ROLE_USER",
  "storePhoneNumber" : null,
  "storeName" : null,
  "latitude" : null,
  "longitude" : null
}

Example response

HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
Content-Length: 253

{
  "accessToken" : "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJUZXN0VXNlcjEiLCJyb2xlcyI6WyJST0xFX1VTRVIiXSwiaWF0IjoxNjEyNTc0NDIxfQ.HEkQD9qA4FG79rr85b3ABRBmmWZdTKG2-nMV39LDOgs",
  "id" : "TestUser1",
  "name" : "테스트 유저 1",
  "storeName" : null
}

회원가입하기(매장)

Post 요청을 사용해서 회원가입을 할 수있다.

HTTP request

POST /auth/signup HTTP/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 310
Host: templet.restapi.com

{
  "id" : "TestUser1",
  "password" : "Password",
  "name" : "테스트 유저 1",
  "phoneNumber" : "전화번호~",
  "address" : "집주소",
  "role" : "ROLE_STORE",
  "storePhoneNumber" : "매장번호",
  "storeName" : "매장이름",
  "latitude" : "위도값",
  "longitude" : "경도값"
}

Example response

HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
Content-Length: 264

{
  "accessToken" : "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJUZXN0VXNlcjEiLCJyb2xlcyI6WyJST0xFX1NUT1JFIl0sImlhdCI6MTYxMjU3NDQyMX0.kcAHIe29Ua2Dg5eZXprsGTzCafqpx2oFeNB-5CJ3ZtI",
  "id" : "TestUser1",
  "name" : "테스트 유저 1",
  "storeName" : "매장이름"
}

아이디 중복 검사하기

Get 요청을 사용해서 아이디 중복확인을 할 수있다.

HTTP request

GET /auth/checkid/TestUser1 HTTP/1.1
Host: templet.restapi.com

Example response

HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY

매장단말기

출입 기록하기

HTTP request

POST /visits HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJUZXN0U3RvcmUxIiwicm9sZXMiOlsiUk9MRV9TVE9SRSJdLCJpYXQiOjE2MTI1NzQ0MDl9.u_x6qnA74tjIBX41DupHWqEerhOimAmb445wEiRcqFM
Content-Length: 110
Host: templet.restapi.com

{
  "storeId" : "TestStore1",
  "visitorId" : "TestUser2",
  "entryTime" : "2021-02-06T10:20:09.2387547"
}

Example response

HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
Content-Length: 2

50

퇴장 기록하기

HTTP request

PUT /visits/51 HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJUZXN0U3RvcmUxIiwicm9sZXMiOlsiUk9MRV9TVE9SRSJdLCJpYXQiOjE2MTI1NzQ0MDl9.u_x6qnA74tjIBX41DupHWqEerhOimAmb445wEiRcqFM
Content-Length: 50
Host: templet.restapi.com

{
  "exitTime" : "2021-02-06T10:20:09.5827574"
}

Example response

HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY

출입 기록 조회하기

HTTP request

GET /visits/Teststore1 HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJUZXN0U3RvcmUxIiwicm9sZXMiOlsiUk9MRV9TVE9SRSJdLCJpYXQiOjE2MTI1NzQ0MTN9.lEvlbhoEQmLJ-9yhbDtYKJTZzjjDGar1Ogk-_uyJOGs
Host: templet.restapi.com

Example response

HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
Content-Length: 871

{
  "visitLogs" : [ {
    "id" : 56,
    "visitor" : {
      "id" : 58,
      "name" : "테스트 유저 3",
      "phoneNumber" : "010-1234-5678",
      "address" : "주소"
    },
    "store" : {
      "id" : 35,
      "storeName" : "매장명1",
      "storePhoneNumber" : "010-1234-5678",
      "address" : "주소"
    },
    "entryTime" : "2021-02-06T08:20:13.9419654",
    "exitTime" : "2021-02-06T10:20:13.946963"
  }, {
    "id" : 58,
    "visitor" : {
      "id" : 59,
      "name" : "테스트 유저 4",
      "phoneNumber" : "010-1234-5678",
      "address" : "주소"
    },
    "store" : {
      "id" : 35,
      "storeName" : "매장명1",
      "storePhoneNumber" : "010-1234-5678",
      "address" : "주소"
    },
    "entryTime" : "2021-02-06T08:20:13.9529677",
    "exitTime" : "2021-02-06T10:20:13.9579639"
  } ]
}

관리자

출입 기록 조회(관리자)

HTTP request

GET /visits?storeName=%EB%A7%A4%EC%9E%A5%EB%AA%851&visitorName=%ED%85%8C%EC%8A%A4%ED%8A%B8+%EC%9C%A0%EC%A0%80+3&time=2021-02-06T09%3A20%3A11.867772300 HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJUZXN0VXNlcjUiLCJyb2xlcyI6WyJST0xFX0FETUlOIl0sImlhdCI6MTYxMjU3NDQxMX0.2qJknZhWTs8Zd0rCkkL2hFsE_J7W1D01D6zFfb9dEe8
Host: templet.restapi.com

Example response

HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
Content-Length: 448

{
  "visitLogs" : [ {
    "id" : 52,
    "visitor" : {
      "id" : 55,
      "name" : "테스트 유저 3",
      "phoneNumber" : "010-1234-5678",
      "address" : "주소"
    },
    "store" : {
      "id" : 33,
      "storeName" : "매장명1",
      "storePhoneNumber" : "010-1234-5678",
      "address" : "주소"
    },
    "entryTime" : "2021-02-06T08:20:11.8437713",
    "exitTime" : "2021-02-06T10:20:11.8497722"
  } ]
}

fcm 세팅

토큰 등록

HTTP request

POST /push HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJUZXN0VXNlcjEiLCJyb2xlcyI6WyJST0xFX1VTRVIiXSwiaWF0IjoxNjEyNTc0NDA1fQ.MyQaCrufKYXkSNZ9n8p5A2D3G-UksGL-pUeZGTlovFw
Content-Length: 58
Host: templet.restapi.com

{
  "userId" : "TestUser1",
  "token" : "Token Value"
}

Example response

HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY