ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 프로젝트 환경분석3(ApolloServer, ApolloClient)
    Etc/WEB 2021. 7. 20. 19:17
    728x90

    server/graphql/aplloServer.ts

     

    이 모듈은 ApolloServer 객체를 생성을 하는데, 인자로 schema, context, dataSources, plugins를 전달한다.

     

    schema

     

    스키마는 데이터 타입의 집합으로, 일종의 API 문서의 역할도 한다. 어떠한 데이터 객체를 반환할지, 특정 요청을 어떻게 처리할 지 등이 작성되어 있다.

    같은 폴더의 schema.ts는 정의된 type과 resolver를 묶어서 반환한다.

     

    context

     

     

    일종의 전역변수 개념으로, context 필드에는 객체 혹은 객체를 반환하는 function이 들어간다.

    해당 config 설정 시 resolver에서 해당 context의 객체를 인자로 받아서 사용이 가능하다.

    req.clientHeader 프로퍼티를 추가해서 전달 해 주는 것으로 보아 사용자 인증에 해당하는 것으로 추측된다.

    그런데 res의 역할을 잘 모르겠다.

     

    dataSources

     

    Data sources are classes that Apollo Server can use to encapsulate fetching data from a particular source, such as a database or a REST API. These classes help handle caching, deduplication, and errors while resolving operations.

     

    https://www.apollographql.com/docs/apollo-server/data/data-sources/#open-source-implementations

     

    Data sources

    Manage connections to databases and REST APIs

    www.apollographql.com

    server 인스턴스 생성 시 dataSource는 함수로 이루어져있는데, 이는 내가 정의한 subclass들의 객체를 return한다.

    그리고 이는 query요청시마다 호출되고, resolver의 context항목에 전달된다.

    MongoDB.get()에서 db를 return하는데, 이것을 인자로 받는 dataSource 메서드를 실행한다.

    해당 메서드는 getRestDataSources의 결과값과 getMongoDataSources(db)의 결과값을 객체에 담아 return 해 준다.

     

    getRestDataSources는 NcpProductAPI클래스의 인스턴스를 담아서 전달한다. 

    이 메서드는 아마 외부 API에서 data를 가져오는 역할을 하는 것 같다.

    NcpProductAPI 인스턴스는 baseURL 프로퍼티를 갖는데, 여기에는 스마트스토어의 protocol, host등의 정보가 담긴 url 문자열이 담긴다.

    또한 fetchById 메서드를 갖는데, 이는 RESTDataSource 클래스의 get 메서드 결과값을 return한다.

     

    (8/13 추가)

    찜버튼 구현을 위해, 외부 API를 이용할 일이 생겨서 다시 구현하게되었다.

    총 해야 할 일은

    1. StoreKeep과 관련한 type과 resolver 정의

    2. resolver에서 사용할 dataSource 수정. (storeKeepAPI 클래스)

     

    1번같은경우는 add, delete keep mutation들은 argument는 storeId 단 하나고, storeKeep type을 정의해서 return 필드로 정의해주면 되었다.

    resolver도 dataSource의 storeKeepAPI의 add/deleteStoreKeep 메서드를 호출하여 해당 값에서 원하는 값만 메서드로 취해서 return해 주면 되었다.

     

    2번은 이제 storeKeepAPI클래스에서 post/delete 요청을 하고, 요청 시 필요한 option들을 지정해준다. (api 요청 보낼 주소, body, header 등)

    추가적으로, error 핸들링까지 해 준다. 

    이것이 storeKeepAPI의 역할인 것 같다.

     

     

    getMongoDataSources메서드는 db를 인자로 받아서, productCollection 필드를 갖는 객체를 return한다.

    여기서 productCollection필드는 ProductCollection 클래스의 인스턴스를 value로 갖는다.

    ProductCollection 클래스는 MongoDataSource를 상속받고, db.collection을 멤버변수로 전달받는다.

    이 클래스의 findById메서드는 productId를 인자로 받아서 ProductFns의 findById를 호출하고, 인자로 db.collection과 productId를 넘긴다.

    이 findById 메서드는 collection에서 _id가 productId와 일치하는 document를 가져온다.

    여기서 NullishUtil의 getOrUndefind 메서드가 사용되는데, 데이터가 없으면 undefined를 반환하는 함수로 추측된다.

     

     

     

    plugins

     

    사용자가 직접 정의한 이벤트 메서드를 추가할 수 있다. 

     

    * 추가 예정

     

     

    ApolloClient

     

    shared/graphql/apolloClient를 먼저 살펴보자. 

    가장 밑의 export 하고 있는 useApollo 메서드는 useMemo hook을 사용하는데, 이는 이전에 연산 해 두었던 값을 재활용함으로써 불필요한 연산 반복을 막기 위한 hook이다. 이 hook은 initialState와 context가 바뀌는 경우에만 initilizeApollo 메서드를 호출하도록 설정이 되어있다.

     

    다음으로, initializeApollo 함수 표현식을 보면,

     

    apolloClient가 존재할 시 해당 값을 _apolloClient에 할당하고, 아닌 경우createApolloClient 메서드를 호출하여 새로운 apolloClient를 생성 해 낸다.

    또, initialState이 존재하면, _apolloClient의 cache에 existingcache와 initialState을 함께 저장한다.

    또, window가 undefined면(즉, 브라우저가 아닌 서버에서 해당 메서드가 실행 중이면) _apolloClient를 바로 return 해 준다.

    다음으로, apolloClient가 존재하지 않는다면, _apolloClient를 할당한다.(apolloClient는 해당 모듈 내에서 전역변수

    마지막으로 _apolloClient를 return하고 메서드가 종료된다.

     

    앞서 apolloClient가 존재하지 않을 때 호출 되는 createApolloClient 메서드를 보면,

     

    새로운 ApolloClient 인스턴스를 생성해내는데, ssrMode의 경우 window가 undefined인지에 대한 결과를 반환한다. 즉, 브라우저에서 실행이 되면 true, 아니면 false가 들어가게 된다.

    다음으로 link 프로퍼티에는 https://www.apollographql.com/docs/react/api/link/introduction/

     

    Apollo Link overview

    Customize Apollo Client's data flow

    www.apollographql.com

    errorLink, persistedQueryLink, httpLink 3개의 값이 들어가있다.

     

    먼저 errorLink는 서버측에서의 response에 있는 error를 구체적으로 알려준다.

    GraphQL operation 실행 중 발생한 에러 또는 네트워크문제로 발생한 에러를 핸들링해준다.

     

    persistedQueryLink 프로퍼티 https://www.apollographql.com/docs/react/api/link/persisted-queries/

     

    Persisted Queries Link

    Replace full queries with generated ID's to reduce bandwidth.

    www.apollographql.com

     

    는 지나치게 큰 크기의 쿼리 전송 문제를 해결하기 위해, query text 원본 대신 64byte 크기의 암호화된 해쉬를 서버에 전송한다. 

    만약 backend에서 이 해쉬를 정상적으로 인식한다면 해당하는 query를 실행 하게 되고,

    정상적으로 인식하지 못한 경우 클라이언트에 해쉬와 query text 원본 전송을 요청하게 된다. 그 후, 이 둘을 매핑하여 나중에 해당 해쉬가 전송됬을 경우 잘 인식하여 그에 매핑되는 query를 실행하게 된다.

     

    마지막으로, httpLink의 경우는 https://www.apollographql.com/docs/react/api/link/apollo-link-http/

     

    HTTP Link

    Get GraphQL results over a network using HTTP fetch.

    www.apollographql.com

     

    HTTP 기반으로 GraphQL operationd을 서버측에 전송 해 주는 terminating link이다.

    CreateHttpLink로 해당 링크를 생성하게 되는데, 

    먼저 uri 옵션에서는 해당 GraphQL opreration을 전송할 endpoint를 넣어준다.

    여기서, isServer 변수를 활용하여 만약 서버사이드에서 해당 operation을 실행하는 경우에는 바로 해당 경로를 적어주고,

    브라우저에서 operation이 실행되는 경우에는 http://localhost:3000까지 입력을 해 준다.

    credentials 옵션에는 same-origin 값을 넣어주어서 같은 origin에서만 요청을 주고 받을 수 있도록 policy를 설정한다.

    fetch는 customizing한 fetcher를 넣어주는데,  여기서 requestInit 부분에 init의 정보를 넣고, context에서 전달된 headers를 넣어준다.

     

    'Etc > WEB' 카테고리의 다른 글

    CI/CD란  (0) 2021.08.31
    웹 기초 용어 정리  (0) 2021.08.27
    directives 기능 사용하여 http 요청 https로 일괄 변환하기  (0) 2021.08.22
    fetch와 axios  (0) 2021.06.14
    Redux의 필요성  (0) 2021.05.17

    댓글

Designed by Tistory.