[쇼핑몰 프로젝트] 3. graphql & firebase

365.48km·2022년 11월 28일
0

나의 개발일지

목록 보기
3/6

1. Firebase란

Firebase란 💡
서버 대신 만들어주는 서비스이다. 대표적인 기능으로 인증, 데이터베이스, 스토리지, 원격 구성, 푸시 알람, 실시간등이 있다.

2. 왜 Firebase를 선택했는가?

원래 사이드 프로젝트로 BE 2명 / FE 1명으로 구성한 쇼핑몰 프로젝트를 구현하던 중 협업 과정에서 BE의 작업 속도에 따라서 데이터를 받아야하는 FE입장에서는 진행함에 있어서 수동적으로 request에만 의존해야 했던 문제가 있었다.
이를 통해, 단순 FE단에서 먼저 구현해보고 BE와 나중에 추가적으로 병합할 수 있으면 작업 속도와 효율성이 좋을 것이라 판단하였습니다. 그렇게 FE단에서도 BE의 흉내를 낼 수 있는 Firebase를 사용해보고 프로젝트를 만들어낼 때, 프로토타입으로 적용하기에 큰 이점이 될 수 있다는 것을 알게 됨.

  • firebase를 이요하면오랜시간을 들여서 백엔드를 모두 구현할 필요가 없다. 개인 프로젝트를 하면서, 백엔드를 할 수 없으니 나에겐 필요한 기능이라고 볼 수 있다.
  • 프로토타입을 만들어 잘 작동하는지 먼저 테스트를 해볼 수 있기 때문에 시간 절약으로서 기능이 좋다.
  • 그럼에도 firebase에는 아직은 장단점이 존재한다.

3. Firebase 장/단점

3.1. FireBase 장점

  • JSON 트리로 스키마가 없는 형태의 데이터를 저장한다.
  • 선호하는 방식을 따라 기존 데이터를 업데이트 할 수 있어 관리하기에 용이하다.
  • 트리 CRUD시 요청에 대한 검증을 따로 하지 않아 쉽게 이해할 수 있다.

3.2. FireBase 단점

  • 스키마가 없기 때문에 데이터 관리가 쉽지 않아 데이터 구조를 살 설계해야한다.
  • 관계성이 없기 때문에 ID를 이용한 참고가 필요하다. (데이터가 많아질수록 복잡해짐)
  • FireBase 보안 규칙을 고려하여 데이터 이름을 정하는 경우도 상당히 복잡해진다.
  • 데이터를 읽을 때 Firebase SDK를 사용하면 페이지네이션이나 검색을 지원하지 않기 때문에 추가 작업이 필요하다.

4.이러한 문제를 보완하기 위해서 필요한 것은?

  • Graphql을 사용하기로 판단하였다.

    스카마가 없기 때문에 데이터 관리의 어려움이 있다. 따라서, 타입 기반의 스키마를 정의하는 graphql 을 연동하여 사용한다면, 좋지않을까...? 판단

5. GRAPHQL과 REST API의 차이는?

  • REST API로 urlhttp 메소드를 통해서 데이터를 패칭하는것에는 대표적으로 두 가지 단점이 존재한다. over-fetching, under-fetching

overfetching 이란?

  • 요청한 것 이상의 불필요한 데이터를 패칭하게 된다.
  • 가령, 상품의 이름, 가격, 브랜드 등의 정보만 알고 싶어도, 어쩔수 없이 하나의 데이터에 들어가는 다른 정보들도 패칭해야 한다.

underfetching 이란?

  • 필요한 정보를 위해 여러개의 request를 해야한다.
  • 가령, 상품의 카테고리 등이 번호로 되어있어서, 상의, 하의, 등의 string정의로된 데이터를 알기 위해서는 따로 카테고리가 정의된 데이터 요청도 해야하므로, 하나의 정보를 위해서 두 개의 request를 해야하는 문제가 발생한다.

REST API 의 단점 GraphQL로 해결

  • 이러한 문제를 해결할 수 있는 것이 Graphql이고, 장기적인 관점에서 앞으로 많은 부분 프론트엔드에서 주류가 될 거라고 판단하여, 공부도 할 겸 Graphql을 선택하고자 하였다.

프로젝트 초기 셋팅

1) server

  const server = new ApolloServer({
    typeDefs: schema,
    resolvers: resolvers,
    context: {
      db: {
        ......
      },
    },
  });

  const app = express();
  await server.start();
  server.applyMiddleware({
    app,
    path: "/graphql",
    cors: {
      origin: ["http://localhost:3000", "https://studio.apollographql.com"],
      credentials: true,
    },
  });
  • AplloServer를 사용하기 위해서 필수로 필요한건 typeDefsresolvers이다.
  • typeDefs에서 스카마를 정의하고, 정의된 스키마에 따라서, resolvers에는 요청에 따라, 데이터가 보내질 형태를 정의하게 된다. EX) Query, Mutation 등

2) 상품 schema


const productSchema = gql`
  type Category {
    category_lg: String!
    category_md: String!
    category_sm: String!
  }
  type Product {
    id: ID!
    brand: String!
    name: String!
    image_url: String!
    origin_price: Int!
    discount: Int!
    new: Boolean!
    category: Category!
    createdAt: Float!
  }

  extend type Query {
    products: [Product!]
    product(id: ID!): Product!
    selectedProducts(
      category_lg: String!
      category_md: String
      category_sm: String
    ): [Product!]
  }
`;

export default productSchema;

3) 상품 Resolver

    products: async (parent, arg) => {
      const products = collection(db, "products");
      const querySnapshot = await getDocs(products);
      const data: DocumentData[] = [];
      querySnapshot.forEach((doc: DocumentData) => {
        const d = doc.data();
        data.push({
          id: doc.id,
          ...d,
        });
      });
      return data;
    },
    product: async (parent, { id }) => {
      const querySnapshot = await getDoc(doc(db, "products", id));
      return {
        ...querySnapshot.data(),
        id: querySnapshot.id,
      };
    },

collection(db, "products") 을 통해서, firebase의 컬렉션에 products로 정의된 컬렉션에 접근을 하고 getDocs()을 사용하여 해당 데이터들을 가져와서 스냅샷을 찍고, 새로운 배열을 만들고 그 배열안에 스냅샷의 데이터를 변형하여 넣도록 한다.foreEach 메소드를 통해서, 각각의 데이터에 id값을 부여하여 return하도록 한다.

Key Point
스냅샷을 만들어서 사용

주의 !!
firebase에서는 기본적으로 제공하는 메소드들이 정해져있고, map은 제공하지 않는다.



참고

profile
이게 마즐까?

0개의 댓글