firebase의 firestore를 db로 사용할 것이다.
server디렉토리에서 파이어베이스 dependency를 설치한다.
yarn add firebase
▼ server/firebase.js
아래 내용이 포함되도록 파이어베이스 설정을 한다.
▼ server/resolvers/product.ts
Query: {
products: async (
parent,
{ cursor = "", showDeleted = false } /*{ db }*/
) => {
const products = collection(db, "products");
const queryOptions: any[] = [orderBy("createdAt", "desc")];
if (cursor) {
const snapshot = await getDoc(doc(db, "products", cursor));
queryOptions.push(startAfter(snapshot));
}
if (!showDeleted) {
queryOptions.unshift(where("createdAt", "!=", null));
}
const q = query(products, ...queryOptions, limit(PAGE_SIZE));
const snapshot = await getDocs(q);
const data: DocumentData[] = [];
snapshot.forEach((doc) => data.push({ id: doc.id, ...doc.data() }));
return data;
},
product: async (parent, { id }) => {
const snapshot = await getDoc(doc(db, "products", id));
return {
...snapshot.data(),
id: snapshot.id,
};
},
},
▼ server/src/cart.ts
Query: {
cart: async (parent, args) => {
const cart = collection(db, "cart");
const cartsnap = await getDocs(cart);
const data: DocumentData[] = [];
cartsnap.forEach((doc) => {
const d = doc.data();
data.push({ id: doc.id, ...d });
});
return data;
// return db.cart;
},
},
CartItem: {
product: async (cartItem, args) => {
const product = await getDoc(cartItem.product);
const data = product.data() as any;
return {
...data,
id: product.id,
};
// return db.products.find((product) => product.id === cartItem.id);
},
},
▼ server/src/resolvers/product.ts
addProduct: async (parent, { imageUrl, price, title, description }) => {
const newProduct = {
price,
imageUrl,
title,
description,
createdAt: serverTimestamp(),
};
const result = await addDoc(collection(db, "products"), newProduct);
const snapshot = await getDoc(result);
return {
...snapshot.data(),
id: snapshot.id,
};
}
updateProduct: async (parent, { id, ...data }) => {
const productRef = doc(db, "products", id);
if (!productRef) throw new Error("존재하지 않는 상품입니다.");
await updateDoc(productRef, data);
const snap = await getDoc(productRef);
return {
...snap.data(),
id: snap.id,
};
}
deleteProduct: async (parent, { id }) => {
const productRef = doc(db, "products", id);
if (!productRef) throw new Error("존재하지 않는 상풉입니다.");
await updateDoc(productRef, { createdAt: null });
return id;
}
▼ server/src/resolvers/cart.ts
addCart: async (parent, { productId }) => {
if (!productId) throw Error("상품 productId가 없습니다.");
const productRef = doc(db, "products", productId);
const cartCollection = collection(db, "cart");
const exist = (
await getDocs(
query(collection(db, "cart"), where("product", "==", productRef)))).docs[0];
let cartRef;
if (exist) {
cartRef = doc(db, "cart", exist.id);
await updateDoc(cartRef, { amount: increment(1) });
} else {
cartRef = await addDoc(cartCollection, {
amount: 1,
product: productRef,
});
}
const cartSnapshot = await getDoc(cartRef);
return {
...cartSnapshot.data(),
product: productRef,
id: cartSnapshot.id,
};
}
updateCart: async (parent, { cartId, amount }) => {
if (amount < 1) throw new Error("수량은 1이상이어야 합니다.");
const cartRef = doc(db, "cart", cartId);
if (!cartRef) throw new Error("장바구니 정보가 없습니다");
await updateDoc(cartRef, { amount });
const cartSnapshot = await getDoc(cartRef);
return {
...cartSnapshot.data(),
id: cartSnapshot.id,
};
}
deleteCart: async (parent, { cartId }) => {
const cartRef = doc(db, "cart", cartId);
if (!cartRef) throw new Error("장바구니 정보가 없습니다");
await deleteDoc(cartRef);
return cartId;
}
executePay: async (parent, { ids }) => {
const deleted = [];
for await (const id of ids) {
const cartRef = doc(db, "cart", id);
const cartSnapshop = await getDoc(cartRef);
const cartData = cartSnapshop.data();
const productRef = cartData?.product;
if (!productRef) throw new Error("상품 정보가 없습니다.");
const product = (await getDoc(productRef)).data() as Product;
if (product.createdAt) {
await deleteDoc(cartRef);
deleted.push(id);
}
}
return deleted;
}
▼ server/src/resolvers/product.ts
updateProduct: async (parent, { id, ...data }) => {
const productRef = doc(db, "products", id);
if (!productRef) throw new Error("존재하지 않는 상품입니다.");
await updateDoc(productRef, { ...data, createdAt: serverTimestamp() });
const snap = await getDoc(productRef);
return {
...snap.data(),
id: snap.id,
};
},
삭제된 상품에 위 사진과 같이 수정 및 복구 버튼이 뜨고 수정완료를 누르면 원래대로 복구된다.
좋은 글 감사합니다.