-
Notifications
You must be signed in to change notification settings - Fork 35
[최은영] sprint2 #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The head ref may contain hidden characters: "sprint2-\uCD5C\uC740\uC601"
[최은영] sprint2 #49
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// 기본 API 주소 설정 | ||
const Base_URL = 'https://panda-market-api-crud.vercel.app'; | ||
|
||
// 게시글 리스트를 가져오는 함수 (page, pageSize, keyword 쿼리 파라미터를 이용) | ||
export function getArticleList(params = { page: 1, pageSize: 10, keyword: '' }) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. params 에 대한 Object 활용 및 디폴트 선언을 한 점 아주 훌륭합니다 ! |
||
|
||
// URL 객체를 생성하여 쿼리 파라미터를 처리 | ||
const url = new URL('${BASE_URL}/articles'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. template literal 을 활용하여 좋은 코드를 작성했습니다 너무좋습니다!
|
||
|
||
// params 객체에서 page, pageSize, keyword 정보를 쿼리스트링에 추가 | ||
Object.entries(params).forEach(([key, value]) => { | ||
if (value !== undefined && value !== '') url.searchParams.append(key, value); | ||
}); | ||
|
||
// fetch로 GET 요청 전달 | ||
return fetch(url) | ||
.then(res => { | ||
// 응답이 실패(2XX 범위 밖)할 시, err.massage 출력한 후 err를 throw | ||
if (!res.ok) throw new Error('목록 조회 실패: ${res.status}'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 주석과 코드가 조금 다른 듯 합니다. |
||
return res.json(); | ||
}) | ||
.catch(err => console.error('getArticleList 에러:', err.message)); | ||
} | ||
|
||
// getArticle() GET 메소드를 사용 | ||
// 특정 게시글 하나를 조회하는 함수 | ||
export function getArticle(articleId) { | ||
// fetch를 이용해 GET 요청 전달 | ||
return fetch('${BASE_URL}/articles/${articleId}') | ||
.then(res => { | ||
if (!res.ok) throw new Error('게시글 조회 실패: ${res.status}'); | ||
return res.json(); | ||
}) | ||
.catch(err => console.error('getArticle 에러:', err.message)); | ||
} | ||
|
||
// createArticle() POST 메소드를 사용 | ||
// Request Body에 title, content, image를 포함한 게시글을 생성하는 함수 | ||
export function createArticle({ title, content, image }) { | ||
// fetch로 POST 요청 전달 | ||
return fetch('${BASE_URL}/articles', { | ||
method: 'POST', // POST 메서드 사용 | ||
headers: { 'Content-Type': 'application/json' }, // 요청에 Json 데이터를 알림. | ||
body: JSON.stringify({ | ||
title, | ||
content, | ||
image, | ||
}), | ||
}) | ||
.then(res => { | ||
if (!res.ok) throw new Error('생성 실패: ${res.status'); | ||
return res.json(); | ||
}) | ||
.catch(err => console.error('createArticle 에러:', err.message)); | ||
} | ||
|
||
// patchArticle() PARCH 메소드를 사용 | ||
// 게시글을 수정하는 함수 | ||
export function patchArticle(articleId, { title, content, image }) { | ||
// fetch로 PATCH 요청 전달 | ||
return fetch('${BASE_URL}/articles/${articleId}', { | ||
method: 'PATCH', // PATCH 메서드 사용 | ||
headers: { 'Content-Type': 'application/json' }, | ||
body: JSON.stringify({ //수정 내용을 JSON으로 전달 | ||
title, | ||
content, | ||
image, | ||
}), | ||
}) | ||
.then(res => { | ||
if (!res.ok) throw new Error('수정 실패: ${res.status}'); | ||
return res.json(); | ||
}) | ||
.catch(err => console,error('patchArticle 에러:', err.message)); | ||
} | ||
Comment on lines
+62
to
+75
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indent (들여쓰기) 를 맞추어 가독성을 신경썼다면 더 좋았을 것 같습니다 ! |
||
|
||
//deleteArticle() : DELETE 메소드 사용 | ||
// 특정 게시글을 삭제하는 함수 | ||
export function deleteArticle(articleId) { | ||
// fetch로 DELETE 요청 전달 | ||
return fetch('${BASE_URL}/articles/${articleId}', { | ||
method: 'DELETE', // DELETE 메서드 사용 | ||
}) | ||
.then(res => { | ||
if (!res.ok) throw new Error('삭제 실패: ${res.ststus}'); | ||
return res.text(); // 삭제 성공 할 시 텍스트로 응답 | ||
}) | ||
.catch(err => console.error('deleteArticle 에러:', err.message)); | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 클래스는 이렇게 한 곳에 모으기 보다는 관점에 따라서 분리했다면 더 좋았을 것 같습니다! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// 상품 클래스 정의 | ||
export class Product { | ||
// 상품 정보 객체 속성 세팅 | ||
constructor(name, description, price, tags = [], images = []) { | ||
this.name = name; //상품명 | ||
this.description = description; //상품 설명 | ||
this.price = price; //상품 가격 | ||
this.tags = tags; //상품 해시태그 배열 | ||
this.images = images; //상품 이미지 배열 | ||
this.favorite = 0; //찜하기 수 (초기값 0) | ||
} | ||
Comment on lines
+4
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
|
||
// favorite 메서드 찜하기 수를 1씩 증가 | ||
favorite () { | ||
this.favoriteCount += 1; //favoriteCount 값을 1씩 증가 | ||
} | ||
} | ||
|
||
// Product를 상속하는 ElectronicProduct 클래스 | ||
export class ElectronicProduct extends Product { | ||
constructor(name, description, price, tags = [], images = [], manufacturer = '') | ||
{ | ||
super(name, description, price, tags, images); // product 속성 | ||
this.manufacturer = manufacturer; // 제조사 정보 추가 저장 | ||
} | ||
} | ||
|
||
// 게시글 클레스 정의 Article 클래스 | ||
export class Article { | ||
// 게시글 정보 객체 속성 | ||
constructor(title, content, writer) { | ||
this.title = title; // 게시글 제목 | ||
this.content = content; // 게시글 내용 | ||
this.writer = writer; // 작성자 이름 | ||
this.likeCount = 0; // 좋아요 수 (초기값 0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 비즈니스적 관점에서 초기 생성시에 0 을 지정해주는 것 좋습니다. 너무 잘하셔서 더 나아간 점을 추가로 피드백 드리자면, |
||
this.createdAt = new Date(); // 객체 생성 시점 현재시간 저장 | ||
} | ||
|
||
// 좋아요 수 1씩 증가시키는 like 메서드 | ||
like() { | ||
this.likeCount += 1; // 호출 할 경우 likeCount가 1 증가 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
const BASE_URL = 'https://panda-market-api-crud.vercel.app'; | ||
|
||
// getProductList: 상품 리스트를 받아오는 함수 (page, pageSize, keyword 쿼리 파라미터를 이용) | ||
export async function getProductList({ page = 1, pageSize = 10, keyword = '' } = {}) { | ||
try { | ||
const url = new URL(`${BASE_URL}/products`); | ||
if (page) url.searchParams.append('page', page); | ||
if (pageSize) url.searchParams.append('pageSize', pageSize); | ||
if (keyword) url.searchParams.append('keyword', keyword); | ||
|
||
const res = await fetch(url); | ||
|
||
if (!res.ok) { | ||
console.error('상품 리스트 조회 실패:', res.status); | ||
return null; | ||
} | ||
|
||
return await res.json(); | ||
} catch (err) { | ||
console.error('getProductList 에러:', err.message); | ||
return null; | ||
} | ||
} | ||
|
||
// getProduct: 특정 상품 하나를 조회하는 함수 | ||
export async function getProduct(productId) { | ||
try { | ||
const res = await fetch(`${BASE_URL}/products/${productId}`); | ||
|
||
if (!res.ok) { | ||
console.error('상품 조회 실패:', res.status); | ||
return null; | ||
} | ||
|
||
return await res.json(); | ||
} catch (err) { | ||
console.error('getProduct 에러:', err.message); | ||
return null; | ||
} | ||
} | ||
|
||
// createProduct: 요청 body에 name, description, price, tags, images 포함하여 상품 생성 | ||
export async function createProduct({ name, description, price, tags, images }) { | ||
try { | ||
const res = await fetch(`${BASE_URL}/products`, { | ||
method: 'POST', | ||
headers: { 'Content-Type': 'application/json' }, | ||
body: JSON.stringify({ name, description, price, tags, images }), | ||
}); | ||
|
||
if (!res.ok) { | ||
console.error('상품 생성 실패:', res.status); | ||
return null; | ||
} | ||
|
||
return await res.json(); | ||
} catch (err) { | ||
console.error('createProduct 에러:', err.message); | ||
return null; | ||
} | ||
} | ||
|
||
// patchProduct: 특정 상품(productId)의 이름, 설명, 가격, 태그, 이미지를 수정하는 함수 | ||
export async function patchProduct(productId, { name, description, price, tags, images }) { | ||
try { | ||
const res = await fetch(`${BASE_URL}/products/${productId}`, { | ||
method: 'PATCH', | ||
headers: { 'Content-Type': 'application/json' }, | ||
body: JSON.stringify({ name, description, price, tags, images }), | ||
}); | ||
|
||
if (!res.ok) { | ||
console.error('상품 수정 실패:', res.status); | ||
return null; | ||
} | ||
|
||
return await res.json(); | ||
} catch (err) { | ||
console.error('patchProduct 에러:', err.message); | ||
return null; | ||
} | ||
} | ||
|
||
// deleteProduct: 특정 상품(productId)을 삭제하는 함수 | ||
export async function deleteProduct(productId) { | ||
try { | ||
const res = await fetch(`${BASE_URL}/products/${productId}`, { | ||
method: 'DELETE', | ||
}); | ||
|
||
if (!res.ok) { | ||
console.error('상품 삭제 실패:', res.status); | ||
return false; | ||
} | ||
|
||
return true; | ||
} catch (err) { | ||
console.error('deleteProduct 에러:', err.message); | ||
return false; | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 전체적으로 indent가 잘 돼있지 않아 코드가 가독성이 떨어지는 것 같습니다! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { Product, ElectronicProduct, Article } from './Classes.js'; | ||
import { getProductList, getProduct, createProduct, patchProduct, deleteProduct } from './ProductService.js'; | ||
import { getArticleList, getArticle, createArticle, patchArticle, deleteArticle } from './ArticleService.js'; | ||
|
||
async function loadProducts() { | ||
const response = await getProductList({ page: 1, pageSize: 10 }); | ||
const products = []; | ||
if (response && response.data) { | ||
for (const item of response.data) { | ||
if (item.tags && item.tags.includes('전자제품')) { | ||
products.push(new ElectronicProduct(item.name, item.description, item.price, item.tags, item.images, item.manufacturer || '')); | ||
} else { | ||
products.push(new Product(item.name, item.description, item.price, item.tags, item.images)); | ||
} | ||
} | ||
} | ||
console.log('만들어진 상품 인스턴스 배열:', products); | ||
return products; | ||
} | ||
|
||
function testArticleService() { | ||
getArticleList({ page: 1, pageSize: 3, keyword: '' }).then(console.log); | ||
getArticle(1).then(console.log); | ||
createArticle({ title: '테스트', content: '내용입니다', image: '' }).then(console.log); | ||
patchArticle(1, { title: '수정', content: '수정된 내용', image: '' }).then(console.log); | ||
deleteArticle(2).then(console.log); | ||
} | ||
|
||
async function testProductService() { | ||
console.log(await getProductList({ page: 1, pageSize: 3, keyword: '' })); | ||
console.log(await getProduct(1)); | ||
console.log(await createProduct({ | ||
name: '테스트 상품', | ||
description: '테스트 설명', | ||
price: 10000, | ||
tags: ['테스트'], | ||
images: [''], | ||
})); | ||
console.log(await patchProduct(1, { | ||
name: '수정상품', | ||
description: '수정 설명', | ||
price: 13000, | ||
tags: ['수정'], | ||
images: [''], | ||
})); | ||
console.log(await deleteProduct(1)); | ||
} | ||
|
||
loadProducts(); | ||
testArticleService(); | ||
testProductService(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
막막할때는 하나씩 해보시는건 어떨까요 ?
은영님처럼 처음 개발을 배우는 사람뿐아니라, 실무에 있는 사람이나, 고연차에 사람들도 막막할때가 있습니다.
그럴때는 조금은 멀리 떨어져서 생각해보거나, 하나하나 차근차근 생각해보는 게 저한테는 도움이 되더라고요 !