[GraphQL] graphQL

mj·2022년 1월 19일
0

What is GraphQL?

Data를 Graph로 표현하는 Language이자 Runtime이다. QL의 Query Language에서 질의어라고 생각할 수 있다. 실제로 프론트엔드에서는 API 데이터를 query하는 언어가 맞다. 하지만 백엔드에서는 Runtime 계층의 역할을 하기도 한다.

Why GraphQL?

Rest API가 존재하지만 왜 GraphQL을 써야 하는가 하면 바로 GraphQL의 장점은 표준이기 때문이다. Swagger를 쓰지 않아도 GraphQL은 schema를 통해 API의 기능 범위를 문서를 통해 공개한다. 또한 over-fetching이나 under-fetching이 일어나지 않는다. (쿼리를 통해 필요한 데이터를 추출하기 때문) 그리고 1개의 EndPoint를 가져 단순하게 사용할 수 있다. 결정적으로 그래프 구조를 가져 새 노드만 추가해주면 버전이 관리가 된다. 모바일 클라이언트에서는 앱이 설치되면 API를 업데이트하지 않는 이상 계속 사용하여야 하는데 GraphQL은 이를 해결할 수 있다. 하지만, 오래된 노드를 처리해야 하기도 하고 이에 대한 유지보수도 해야 한다.

GraphQL API

{
	person(personID: 4){
    	name
        birthYear
    }
}

위 쿼리는 ID가 4인 person의 name과 birthYear를 요청한다.

문서(Document)

기본적인 GraphQL 요청을 문서(Document)라고 한다. 문서에는 Query, mutation, subscribe, fragment가 포함된다. 변수와 meta-data도 포함될 수 있다.

query GetEmployees($active: Boolean!){
	allEmployees(active: $active){
    	...employeeInfo
    }
}
fragment employeeInfo on Employee {
	name
    email
    startDate
}

query

GraphQL에서 Query는 읽기 전용으로 데이터를 추출한다.

mutation

GraphQL에서 mutation은 데이터를 변경한 후 추출한다.

subscription

GraphQL에서 subscription은 실시간으로 데이터 변경 내용을 받는다 socket 통신을 한다. data polling보다 효율적이다.

필드(Field)

GraphQL에서 Field는 추출해야 할 객체의 개별 정보 단위를 기술한 것이다. 스칼라 필드는 query에서 leaf값을 나타낸다. 스칼라 타입으로는 Int, String, Float, Boolean이 있다.

{
	me { # 객체를 기술한 필드
    	email #스칼라 필드
        birthday { # 객체를 기술한 필드
            month # 스칼라 필드
            year # 스칼라 필드
        }
        friends { #객체를 기술한 필드
        	name # 스칼라 필드
        }
    }
}

meta field

__type 또는 __schema라는 Root Field로 시작하는 필드를 메타 필드라고 한다. 이러한 쿼리를 내향성 쿼리(Introspective query)라고 한다.

위 쿼리는 해당 스키마가 지원하는 모든 타입을 반환하며 각 타입별 설명도 포함한다.
단일 타입에 대한 정보는 __type을 사용하여 확인한다.

위 쿼리는 Commit 타입을 지원하는 모든 필드를 인수와 함께 반환한다.

레코드 지정하기

단일 레코드 지정하기

query UserInfo {
	user(email: "jane@doe.name") {
    	firstName
        lastName
        username
    }
}

user 필드의 괄호안의 email을 필드 인수(filed arguments)라고 한다.
단일 레코드를 표현하고, 인수값이 꼭 데이터베이스상에 존재하는 고유한 값이어야 한다.
GraphQL에서는 모든 객체를 단일 레코드 필드로 관리한다.

query OrgInfo {
	organization(login: 'jscomplete') {
    	name
        description
        websiteUrl
        repositoies (first: 10){
          nodes {
            	  name
            }
        }
    }
}

위의 깃허브API(az.dev/github.api)에서는 user, repository, project, organization이 단일 레코드 필드에 해당한다.
레코드 수를 제한할 때는 인수(first or last)를 통해 제한할 수 있다.

레코드 정렬하기

레코드를 정렬할 때는 created_at, upated_at, pushed_at, Name, Stargazer 등 다양한 필드를 사용해서 정렬할 수 있다. (github api에서)

query orgReposByName {
	organization(login: "jscomplete") {
    	repositories(first: 10, orderBy: {field: NAME, direction: ASC}) {
        	node {
            		name
            }
        }
    }
}

edge 필드 사용하기

...
edges {
    cursor
    node {
    	name
    }
}

edge 필드는 부모 노드로 추가하면, 페이지 매김한 레코드의 리스트를 나타낸다. 이때, Connection은 서로 연결된 노드들을 가리킨다. (graph의 관계에서 유례)

검색 및 필터링

graphql은 필드 인수를 통해 필터링 조건이나 검색어를 지정해서 list가 반환하는 결과의 범위를 좁힐수 있다.

지시문을 사용한 응답 변경

@로 시작하는 문자열을 사용한다. 모든 schema는 3가지 기본 지시문을 사용할 수 있는데, 그것은 @include, @skip, @deprecated 이다.

query AllDirectives {
	__schema {//내향성쿼리 
    		directives {
            		name
                    description
                    locations 
                    args {
                    	name
                        description
                        defaultValue
                    }
            }
    }
}

내용의 결과를 보면 @include와 @skip은 if와 같은 조건을 인수로 사용하고, @deprecated 지시문은 reason이라는 인수를 필요로 한다.

변수

재사용되는 값이 있을 때, 하드코딩 되는 일을 방지하기 위하여 변수를 사용한다. 덕분에 쿼리 또한 재사용할 수 있다. 앞에 $를 붙이고 타입을 선언할 수 있고, 값을 대입할 수도 있다.

0개의 댓글