[GraphQL] GraphQL에 대해 알아보자(1)

rondido·2022년 12월 22일
0

GraphQL

목록 보기
3/5
post-thumbnail

GraphQL

GraphQL 은 API를 위한 쿼리 언어이며 타입 시스템을 사용하여 쿼리를 실행하는 서버사이드 런타임입니다. GraphQL은 특정한 데이터베이스나 특정한 스토리지 엔진과 관계되어 있지 않으며 기존 코드와 데이터에 의해 대체됩니다.

쿼리와 결과의 형태는 동일하다.


GraphQL 시작하기

{
  person {
    name
  }
}

위 처럼 명확하게 person에 대한 아이디를 입력하지 않으며 아래와 같은 에러와 함께 Id를 정확하게 명시해달라고 함.

{
  "errors": [
    {
      "message": "must provide id or personID",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "person"
      ]
    }
  ],
  "data": {
    "person": null
  }
}
{
  person(personID:1) {
    name
  }
}
{
  "data": {
    "person": {
      "name": "Luke Skywalker"
    }
  }
}

Ctrl + Space 키를 통해 어떤 값들이 존재하는지 확인할 수 있고, 자동완성 기능이 포함되어 있다.

쿼리에 주석을 추가할 수 있다. Ctrl + / 단축키를 이용

Arguments 인자

{
  person(personID:1) {
    name
    birthYear
    gender
    skinColor
    homeworld {
      name
    }
    filmConnection{
      edges{
        node{
          title
          episodeID
          director
          releaseDate
          planetConnection{
            edges{
              node{
                name
              }
            }
          }
        }
      }
    }
    
  }
}

personID:1이 인자 속하는데 personID로 특정 데이터를 가져올 수 있다.


중첩 사용

쿼리에 필드 이름이 같은데 인자를 다르게 조회하고 싶은 경우

{
   person(personID:1){
    name      
  }
  person(personID:2){
    name      
  }
}

위 쿼리를 사용하였을 때는 중첩으로 인한 에러가 발생한다.
그렇기 때문에 각 persionID 마다 별칭을 사용하여 쿼리를 실행 시켜야한다.

{
  person1 : person(personID:1){
    name      
  }
  person2: person(personID:2){
    name      
  }
}

Fragment

앱에서 상대적으로 복잡한 페이지가 있다고 가정해보자. 친구를 가진 두 영웅을 순서대로 요청 했을 때 쿼리가 복집해질 수 있다. 이렇게되면 필드를 최소 두번 반복해야 한다.

이것이 프래그먼트라는 재사용 가능한 단위가 GraphQL에 포함된 이유다. 프래그먼트를 사용하면 필드셋을 구성한 다음 필요한 쿼리에 포함시킬 수 있다.

{
  person1 : person(personID:1){
   ...personInfo
  }
  person2: person(personID:2){
   	name    
    filmConnection{
      edges{
        node{
          title
        }
      }
    }
	}
}
  
  
fragment personInfo on Person{
	  filmConnection{
      edges{
        node{
          title
        }
      }
    }	
}

person1과 person2의 차이점을 보면 아래에서 똑같이 반복되는 내용들을 스프레이드 문법을통해 똑같은 쿼리의 결과를 도출할 수 있다.

Fragment안에 변수

$를 앞에 명시해줌으로써 변수를 사용하겠다고 선언

query($first:Int =1)
{
  person1 : person(personID:1){
   ...personInfo
  }
  person2: person(personID:2){
   	name    
    filmConnection{
      edges{
        node{
          title
        }
      }
    }
	}
}
  
  
fragment personInfo on Person{
	  filmConnection(first:$first){
      edges{
        node{
          title
        }
      }
    }	
}

$first로 변수를 선언하여 int 타입으로 1개만 조회하겠다의 명시로 통해 person1은 한개만 조회하게 된다.

작업이름

작업 타입은 쿼리, 뮤테이션,구독이 될 수 있으며, 어떤 작업의 타입인지를 기술함.

query 뒤에다가 이름을 붙여줌으로써 작업이름을 지정할 수 있고 코드를 덜 헷갈리게 하기 위해 좋다.

디버깅이나 서버 측에서 로깅하는데에 매우 유용하다.


변수

쿼리는 문자열로 전달
동적으로 쿼리를 조회할 필요가 있음
동적 값을 별도로 전달할 방법인 변수 제공

밑에 하단에 보면 variables에서 입력 가능

{
  "first": 1,
  "personId": "5"
}

이렇게하면 person1에서 값이 3개가 나온다.
다양한 인자를 통해 동적으로 조회할 수 있다.


지시어

if문 사용 가능

query PersonInfo($first:Int, $personId:ID,$wtihfile:Boolean = false){
  person1 : person(personID:$personId){
   ...personInfo
  }
  person2: person(personID:2){
   	name    
    filmConnection{
      edges{
        node{
          title
        }
      }
    }
	}
}
  
  
fragment personInfo on Person{
  name
	  filmConnection(first:$first) @include(if:$wtihfile){
      edges{
        node{
          title
        }
      }
    }	
}
  • @include(if:Boolean): 인자가 true인 경우에만 이 필드를 결과에 포함
  • @skip(if:Boolean)인자가 true이면 이 필드를 건너뜀.

뮤테이션

쿼리는 데이터를 가져오는 것
뮤테이션은 데이터를 수정하는 것

Apllo Studio를 사용

https://www.apollographql.com/blog/community/backend/8-free-to-use-graphql-apis-for-your-projects-and-demos/ 사이트를 통해 뮤테이션을 실습 해보기


인자

GraphQL 객체 타입의 모든 필드는 0개 이상의 인수를 가질 수 있습니다

type Starship{
	id: ID!,
    name:String!,
    length(unit:Length:METER): Float
}

스칼라

객체 타입은 이름과 필드를 가짐
타입을 타고 가다가 결국 쿼리의 끝에선 구체적인 데이터로 해석되어야함.
데이터 최종 마지막 타입을 스칼라 타입이라고 한다..

type Person implements Node {
  """The name of this person."""
  name: String

  """
  The birth year of the person, using the in-universe standard of BBY or ABY -
  Before the Battle of Yavin or After the Battle of Yavin. The Battle of Yavin is
  a battle that occurs at the end of Star Wars episode IV: A New Hope.
  """
  birthYear: String

  """
  The eye color of this person. Will be "unknown" if not known or "n/a" if the
  person does not have an eye.
  """
  eyeColor: String

  """
  The gender of this person. Either "Male", "Female" or "unknown",
  "n/a" if the person does not have a gender.
  """
  gender: String

  """
  The hair color of this person. Will be "unknown" if not known or "n/a" if the
  person does not have hair.
  """
  hairColor: String

  """The height of the person in centimeters."""
  height: Int

  """The mass of the person in kilograms."""
  mass: Float

  """The skin color of this person."""
  skinColor: String

  """A planet that this person was born on or inhabits."""
  homeworld: Planet
  filmConnection(after: String, first: Int, before: String, last: Int): PersonFilmsConnection

  """The species that this person belongs to, or null if unknown."""
  species: Species
  starshipConnection(after: String, first: Int, before: String, last: Int): PersonStarshipsConnection
  vehicleConnection(after: String, first: Int, before: String, last: Int): PersonVehiclesConnection

  """The ISO 8601 date format of the time that this resource was created."""
  created: String

  """The ISO 8601 date format of the time that this resource was edited."""
  edited: String

  """The ID of an object"""
  id: ID!
}

String, Int, ID, Float, Date 등 다양한 스칼라 타입이 존재한다.


Interface

특정 필드들을 포함하는 추상 타입

해당 인터페이스를 구현한 탕비들이 가져야 할 필드 정의

Inline Fragments 가 interface나 Union 타입에서 쓰인다고 했었음


profile
개발 옆차기

0개의 댓글