GraphQL은 어떠한 백엔드 프레임워크나 프로그래밍 언어든 함께 사용할 수 있다.
1. 타입시스템
GraphQL 쿼리 언어는 기본적으로 객체의 필드를 선택하는 것을 알 수 있다.
예) 1) root 객체로 시작
2) hero 필드를 선택
3) hero에 의해 반환된 객체에 대해 name과 appearIn 필드를 선택
GraphQL 쿼리의 형태가 결과와 거의 일치하기 때문에 서버에 대해 모르는 상태에서 쿼리가 반환할 결과를 예측할 수 있다. 하지만 서버에 요청할 수 있는 데이터에 대한 정확한 표현을 갖는 것이 좋다.
그래서 어떤 필드를 선택할 수 있는지, 어떤 종류의 객체를 반환할 수 있는지, 하위 객체에서 사용할 수 있는 필드가 무엇인지, 이것이 바로 스키마가 필요한 이유이다.
모든 GrpahQL 서비스는 해당 서비스에서 쿼리 가능한 데이터들을 완벽하게 설명하는 타입들을 정의하고, 쿼리가 들어오면 해당 스키마에 대해 유효성 검사 후 실행한다.
2. 타입 언어
GrpahQL 서비스는 어떤 언어로도 작성할 수 있는데 어느 특정 언어 문법에 의존할 수는 없기 때문에 GrpahQL 스키마 언어를 사용한다. 이거는 쿼리 언어와 비슷하며 GrpahQL 스키마를 언어에 의존적이지 않게 해준다.
3. 객체 타입과 필드
GrpahQL 스키마의 가장 기본적인 구성 요소는 객체 타입이다.
객체 타입은 서비스에서 가져올 수 있는 객체의 종류와 그 객체의 필드를 나타낸다.
1) Character는 GraphQL 객체 타입이다. 즉, 필드가 있는 타입이다. 스키마의 대부분의 타입이 객체 타입이다.
2) name과 appearIn은 Character 타입의 필드이다. 즉 name과 appearIn은 GraphQL 쿼리의 Character 타입 어디서든 사용할 수 있는 필드이다.
3) String은 내장된 스칼타 타입 중 하나이고 이는 스칼라 객체로 해석되는 타입이고 쿼리에서 하위 선택을 할 수 없다.
4) String!은 필드가 non-nullable인 것을 의미한다. 즉 이 필드를 쿼리할 때 GraphQL 서비스가 항상 값을 반환한다는 것을 의미한다. 타입 언어에서는 이것을 느낌표로 나타낸다.
5) [Episode]! Episode 객체의 배열을 나타낸다. 또한 non-nullable이어서 appearIn 필드를 쿼리할 때 항상 배열을 기대할 수 있다.
3. 인자
GraphQL 객체 타입의 모든 필드는 0개 이상의 인수를 가질 수 있다.
모든 인수에는 이름이 있다. 함수가 순서있는 인자를 가지고 오는 JavaScript나 Python과 같은 언어와 달리 GraphQL의 모든 인자는 특별한 이름으로 전달된다. 이 경우, length 필드는 하나의 인자 unit을 가진다.
인자는 필수거나 선택적일수 있다. 인자가 선택적일경우 기본값을 정의할 수 있다. unit인자가 전달되지 않으면 METER로 설정된다.
4. 쿼리 & 뮤테이션 타입
스키마 대부분의 타입은 일반 객체 타입이지만 스키마 내에는 특수한 두 가지 타입이 있다.
모든 GraphQL 서비스는 query 타입을 가지며 mutation 타입은 가질 수도 있고 가지지 않을 수도 있다. 이러한 타입은 일반 객체 타입과 동일하지만 모든 GraphQL 쿼리의 진입점(entry point)을 정의하므로 특별하다.
예)
여기서는 즉, GraphQL 서비스가 hero 및 droid 필드가 있는 query 타입이 있어야 한다.
뮤테이션 타입도 필드를 정의하면 쿼리에서 호출할 수 있는 루트 뮤테이션 필드로 사용할 수 있다.
스키마에 대한 진입점이라는 특수한 점 이외의 쿼리 타입과 뮤테이션 타입은 다른 GraphQL 객체 타입과 동일하고 해당 필드는 정확히 동일한 방식으로 작동한다.
5. 스칼라 타입
GrpahQL 객체 타입은 이름과 필드를 가지지만, 어떤 시점에서 이 필드는 구체적인 데이터로 해석되어야 한다.
이것이 스칼라 타입이 필요한 이유이다. 즉 쿼리의 끝을 나타낸다.
GraphQL에서 기본 제공되는 스칼라 타입은 다음과 같다.
1) Int : 부호가 있는 32비트 정수
2) Float : 부호가 있는 부동소수점 값
3) String : UTF-8 문자열
4) Boolean : true 또는 false.
5) ID : ID 스칼라 타입은 객체를 다시 요청하거나 캐시의 키로서 자주 사용되는 고유 식별자를 나타낸다. ID 타입은 String과 같은 방법으로 직렬화되지만, ID로 정의하는 것은 사람이 읽을 수 있도록 하는 것이 아니다.
대부분의 GraphQL 구현에는 커스텀 스칼라 타입을 지정할 수 있는데
scalar Date
이와 같이 Date 타입을 정의할 수 있다.
이 타입을 직렬화, 역 직렬화, 유효성 검사하는 법을 구현할 수 있다. 예를 들어 Date 타입을 정수형 타임스탬프로 직렬화해야 한다는 것을 지정할 수 있다. 그리고 클라이언트는 모든 날짜 필드에 대해 해당 타입을 기대할 수 있다.
6. 열거형 타입
Enums라는 열거형 타입은 특정 값들로 제한되는 특별한 종류의 스칼라이다. 이를 통해
1) 타입의 인자가 허용된 값 중 하나임을 검증
2) 필드가 항상 값의 열거형 집합 중 하나가 될 것임을 타입 시스템을 통해 의사소통
이렇게 사용할 수 있고 Episode 타입을 사용할 때 마다 NEWHOPE, EMPIRE, JEDI 중 하나 일 것이다.
7. 리스트와 Non-Null
객체 타입, 스칼라 타입, 열거형 타입은 GraphQL 에서 정의할 수 있는 유일한 타입이다. 하지만 스키마의 다른 부분이나 쿼리 변수 선언에서 타입을 사용하면 해당 값의 유효성 검사를 할 수 있는 타입 수정자(type modifiers) 를 적용할 수 있다.
String 타입을 사용하고 뒤에 !을 붙여서 non-null로 표시했는데 non-null 타입 수정자는 필드에 대한 인자를 정의할 때도 사용할 수 있다. 이는 GraphQL 서버가 문자열이나 변수 상관없이 null값이 해당 인자로 전달되는 경우, 유효성 검사 오류를 반환하게 한다.
리스트도 비슷하게 동작하는데 타입 수정자를 사용하여 타입을 List로 표현할 수 있다. 이 필드는 해당 타입의 배열을 반환한다. [ ] 로 묶는 것으로 표현된다. 유효성 검사 단계에서 해당 값에 대한 배열이 필요한 인자에서도 동일하게 작동한다.
이 경우 list 자체는 null일 수 있지만 null값을 가질 수는 없다.
이 경우는 list 자체는 null일 수 없지만 null값을 가질 수는 있다.
필요에 따라 여러 개의 null, list 수정자를 중첩할 수 있다.
8. 인터페이스
GraphQL도 인터페이스를 지원한다.
인터페이스는 이를 구현하기 위해 타입이 포함해야하는 특정 필드들을 포함하는 추상 타입이다.
즉, interface를 하면 interfcae가 가지고 있는 인자와 리턴 타입을 가져야 한다.
9. 유니온 타입
유니온 타입은 인터페이스와 유사하지만, 타입 간에 공통 필드를 특정하지 않는다
예) union SearchResult = Human | Droid | Starship
스키마에서 SearchResult 타입을 반환할 때마다 Human, Droid, Starship을 얻을 수 있다.
유니온 타입의 멤버는 구체적인 객체 타입이어야 한다.
인터페이스나 유니온 타입에서 다른 유니온 타입을 사용할 수 없다.
이 경우 SearchResult 유니온 타입을 반환하는 필드라면, 어떤 필드라도 쿼리할 수 있는 조건부 프래그먼트를 사용해야 한다.
10. 입력 타입
지금까지 열거형 타입이나 문자열과 같은 스칼라 값을 인자로 필드에 전달하는 방법에 대해서만 설명했는데 복잡한 객체도 쉽게 전달할 수 있다. 이는 뮤테이션에서 유용하다.
뮤테이션은 생성될 전체 객체를 전달하고자 할 수 있다.
GraphQL 스키마 언어에서 입력 타입은 일반 객체 타입과 정확히 같지만, type 대신 input 을 사용합니다.
예)
이 예제는 뮤테이션에서 입력 객체 타입을 사용하는 방법이다.
입력 객체 타입의 입력란은 입력 객체 타입을 참조할 수 있지만, 입력 및 출력 타입을 스키마에 혼합할 수는 없다. 또한 필드에 인자를 가질 수 없다.
'Javascript > Graphql' 카테고리의 다른 글
[Graphql] 3. React-Apollo (0) | 2021.12.23 |
---|---|
[Graphql] 1. graphql (0) | 2020.06.15 |