๐Ÿš€ 1๋‹จ๊ณ„ - ํšŒ์› ๊ธฐ๋Šฅ

์žฅ๋ฐ”๊ตฌ๋‹ˆ ์„œ๋น„์Šค์˜ ํšŒ์› ๊ธฐ๋Šฅ ๊ตฌํ˜„ํ•˜๊ธฐ

  • ํšŒ์›๊ฐ€์ž…
    • ์•„์ด๋”” ์ค‘๋ณต์ด๋ฉด ์˜ˆ์™ธ
  • ๋กœ๊ทธ์ธ
    • id, ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž˜๋ชป๋˜์—ˆ์„ ๋•Œ ์˜ˆ์™ธ
    • ์ •์ƒ์ ์œผ๋กœ ๋กœ๊ทธ์ธ ๋  ๊ฒฝ์šฐ token๊ณผ name ๋„˜๊ธด๋‹ค.
  • ์ˆ˜์ •
    • ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜๋ฉด ์ˆ˜์ • ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • name ์ˆ˜์ • ๊ฐ€๋Šฅํ•˜๋‹ค.
    • ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์„ ๋•Œ ์˜ˆ์™ธ
  • ํƒˆํ‡ด
    • ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•ด์•ผ ํƒˆํ‡ดํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ํ‹€๋ฆด๊ฒฝ์šฐ ์˜ˆ์™ธ

API ๋ช…์„ธ

2๋‹จ๊ณ„ ์ถ”๊ฐ€ ๋ช…์„ธ

Products

POST /products

// request
{
	"name": String
	"price": int
	"imageUrl": String
}

// response 201 created
Header {
	"Location": "/products/{productId}"
}

GET /products

// request

//response
200 OK
{
	[
			{
			"id": Long,
			"name": String
			"price": int
			"imageUrl": String
		},
		{
			"id": Long,
			"name": String
			"price": int
			"imageUrl": String
		}
	]
}

๋‹จ์ผ ์•„์ดํ…œ ์กฐํšŒ

GET /products/{productId}

// request

// response
200 OK
{
"id" : Long
"name": String 
"price": int
"imageUrl": String
}

// productId ์—†๋Š” ๊ฒฝ์šฐ 404 NOT FOUND

DELETE /products/{productId}

// request

// response
204 No Content

// productId ์—†๋Š” ๊ฒฝ์šฐ 404 NOT FOUND

CartItem

  • ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ
  • ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์‚ญ์ œ
  • ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ „์ฒด ์‚ญ์ œ
  • ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์กฐํšŒ

์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ

POST /customers/me/carts

// request
Header {
 "Authorization": accessToken
}

Body
{
  "productId": Long
}

// response
Header {
	"Location": "/customers/cart/{cartItemId}"
}

201 Created
Body{
	"id" : Long,
	"productId" : Long,
	"name" : String,
	"price" : int, 
	"imageUrl" : String,
	"quantity" : int,
}

// accessToken์ด ์œ ํšจํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ 401 Unauthorized
// productId๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ 404 Not Found
// ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์ด๋ฏธ product๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ 400 Bad Request

์žฅ๋ฐ”๊ตฌ๋‹ˆ ์กฐํšŒ

GET /customers/me/carts

// request
Header {
 "Authorization": accessToken
}

//response
200 OK
{
	[
			{
			"id": Long,
			"productId" : Long,
			"name": String
			"price": int
			"imageUrl": String
			"quantity": int
		},
		{
			"id": Long,
			"productId" : Long,
			"name": String
			"price": int
			"imageUrl": String
			"quantity": int
		}
	]
}

// ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์•„๋ฌด๋Ÿฐ ์ƒํ’ˆ์ด ์—†์œผ๋ฉด empty List
// ํ† ํฐ์ด ์œ ํšจํ•˜์ง€ ์•Š์œผ๋ฉด 401 Unauthorized

์žฅ๋ฐ”๊ตฌ๋‹ˆ ์‚ญ์ œ

DELETE /customers/me/carts/{cartItemId}

// request
Header {
 "Authorization": accessToken
}

// response
204 No Content

// ํ† ํฐ์ด ์œ ํšจํ•˜์ง€ ์•Š์œผ๋ฉด 401 Unauthorized
// cartItemId๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ 404 NOT FOUND
// productId๊ฐ€ ์‚ฌ๋ผ์ ธ์žˆ๋Š” ๊ฒฝ์šฐ ์ถ”ํ›„ ๊ณ ๋ ค

์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ „์ฒด ์‚ญ์ œ

DELETE /customers/me/carts

// request
Header {
 "Authorization": accessToken
}

// response
204 No Content

// ํ† ํฐ์ด ์œ ํšจํ•˜์ง€ ์•Š์œผ๋ฉด 401 Unauthorized

์žฅ๋ฐ”๊ตฌ๋‹ˆ ๊ฐœ์ˆ˜ ์ˆ˜์ •

PUT /customers/me/carts/{cartItemId}

// request
Header {
 "Authorization": accessToken
}

Body
{
  "quantity": int
}

// response
200 ok

Body{
	"id" : Long,
	"productId" : Long,
	"name" : String,
	"price" : int, 
	"imageUrl" : String,
	"quantity" : int,
}

// accessToken์ด ์œ ํšจํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ 401 Unauthorized
// cartItemId๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ 404 Not Found

Order

POST /customers/orders

// request
Header {
 "Authorization": accessToken
}

Body
{
  [
		{
			"cartItemId": Long,
			"quantity": int
		},
		{
			"cartItemId": Long,
			"quantity": int
		},
		...
	]
}

// response
Header {
	"Location": "/customers/orders/{orderId}"
}

// accessToken์ด ์œ ํšจํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ 401 Unauthorized
// cartItemId๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ 404 Not Found
// quantity๊ฐ€ 0 ์ดํ•˜์ธ ๊ฒฝ์šฐ 400 Bad Request

๋‹จ์ผ ์ฃผ๋ฌธ ๋‚ด์—ญ ์กฐํšŒ

GET /customers/orders/{orderId}

// request
Header {
 "Authorization": accessToken
}

// response
200 OK
{
	"id" : Long,
	"orderDetails" : [
		{
			"productId": Long
			"quantity" : int
	    "price" : int
			"name" : String
	    "imageUrl" : String
		},
		{
			"productId": Long
			"quantity" : int
	    "price" : int
			"name" : String
	    "imageUrl" : String
		},
		// ...
	]
}

// accessToken์ด ์œ ํšจํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ 401 Unauthorized
// orderId ์—†๋Š” ๊ฒฝ์šฐ 404 NOT FOUND
// customer๊ฐ€ orderId์— ๋Œ€ํ•œ ๊ถŒํ•œ์ด ์—†๋Š” ๊ฒฝ์šฐ 401 Unauthorized (๊ทธ๋‹ˆ๊นŒ ๋‚ด ์ฃผ๋ฌธ ๋‚ด์—ญ์„ ๋‚จ์ด ๋ณด๋ ค๊ณ  ํ• ๋•Œ)

GET /customers/orders

*/*/ request
Header {
 "Authorization": accessToken
}

// response
200 OK
{
	[
		"id" : Long,
		"orderDetails" : [
			{
				"productId": Long
				"quantity" : int
		    "price" : int
				"name" : String
		    "imageUrl" : String
			},
			{
				"productId": Long
				"quantity" : int
		    "price" : int
				"name" : String
		    "imageUrl" : String
			}
		]
	],
	[
		"id" : Long,
		"orderDetails" : [
			{
				"productId": Long
				"quantity" : int
		    "price" : int
				"name" : String
		    "imageUrl" : String
			},
			{
				"productId": Long
				"quantity" : int
		    "price" : int
				"name" : String
		    "imageUrl" : String
			}
		]
	]
	// ...
}

// accessToken์ด ์œ ํšจํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ 401 Unauthorized
  • ๋ฐฑ์—”๋“œ
    • 1๋‹จ๊ณ„
      • ํšŒ์›๊ฐ€์ž…
      • ๋กœ๊ทธ์ธ
      • ์ˆ˜์ •
      • ํƒˆํ‡ด

ํšŒ์›๊ฐ€์ž…

POST /customers

// request
{
  "loginId": string,
  "name": string,
  "password": string
}
// response

// HEADER
// Location: "/customers/me"

// 201
{
	"loginId": string,
	"name": string
}

// 400 Bad Request

๋กœ๊ทธ์ธ

POST /login

// request
{
 	"loginId": string,
	"password": string
}
// response 

// 200
{
 	"accessToken": string,
	"name": string
}

// 401 Unauthorized (๋กœ๊ทธ์ธ ์‹คํŒจ)
  • id, ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž˜๋ชป๋˜์—ˆ์„ ๋•Œ

์ •๋ณด ์กฐํšŒ

GET /customers/me

headers: {
      Authorization: `Bearer ${accessToken}`,
},
// 200 OK response

{
	"loginId": string, 
	"name": string
}

//401 Unauthorized
//ํ† ํฐ์ด ์œ ํšจํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ

//404 Not Found
//์กด์žฌํ•˜์ง€ ์•Š๋Š” ํšŒ์›์ผ ๊ฒฝ์šฐ

// ํ˜„์žฌ๋Š” body์— String์œผ๋กœ ์˜ค๋ฅ˜ ๋ฉ”์„ธ์ง€๊ฐ€ response ๋จ
{
	"์กฐํšŒ ์‹คํŒจ!" // 2์ฐจ์—์„œ๋Š” JSON๊ฐ์ฒด๋กœ ๋ณด๋‚ด์ž
}

์ˆ˜์ •

PUT /customers/me

// response

// 200
{
	"name": string
}

// 400 Bad Request
// ๋น„๋ฐ€๋ฒˆํ˜ธ ์ผ์น˜ํ•˜์ง€ ์•Š์„๋•Œ
// ์•„์ด๋””๊ฐ€ ์ด๋ฉ”์ผ ํ˜•์‹์ด ์•„๋‹ ๋•Œ

// 404 Not Found
// ์กด์žฌํ•˜์ง€ ์•Š๋Š” ํšŒ์›์ผ ๋•Œ
  1. ๋“ค์–ด๊ฐ€์„œ ์ˆ˜์ •ํ•˜๊ณ  ๋น„๋ฐ€๋ฒˆํ˜ธ ์ณ์•ผ ํ™•์ •
headers: {
      Authorization: `Bearer ${accessToken}`,
},
// request

{
	"loginId": string, 
	"name": string,
	"password": string // ์ˆ˜์ • ํ™•์ •์šฉ ๋น„๋ฐ€๋ฒˆํ˜ธ 
}

ํƒˆํ‡ด

DELETE /customers/me

  • ํƒˆํ‡ด๋ฅผ ๋น„๋ฐ€๋ฒˆํ˜ธ ํ•œ๋ฒˆ ๋” ์น˜๊ณ  ํƒˆํ‡ด์‹œํ‚ค๊ธฐ
headers: {
      Authorization: `Bearer ${accessToken}`,
},
// request

{
	"password": string,
}
// response 

**// 204 no content**

// 400 Bad Request
// ๋น„๋ฐ€๋ฒˆํ˜ธ ์ผ์น˜ํ•˜์ง€ ์•Š์„๋•Œ

// 404 Not Found
// ์กด์žฌํ•˜์ง€ ์•Š๋Š” ํšŒ์›์ผ ๊ฒฝ์šฐ

//ํ† ํฐ์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ