GraphQL 기본

박상욱·2022년 3월 28일
0

GraphQL

목록 보기
3/4

GraphQL 기본 문법

요청

{
  hero {
    name
  }
}

결과 (json )

{
  "data": {
    "hero": {
      "name": "R2-D2"
    }
  }
}

쿼리와 결과가 정확히 동일한 형태인 것을 볼 수 있습니다.
이것이 GraphQL의 핵심입니다.
항상 기대 한 결과를 얻을 수 있습니다. 서버에서 클라이언트가 요청하는 필드를 정확히 알고있기 때문입니다.

rest api같은경우는 서버개발자가 docs를 내려주면 알수는 있지만 docs가 최신화가 되어있지 않거나 docs가 없을경우에는 서버에 요청을 해야지만 응답값을 알 수 있다.
하지만 GraphQL을 사용하게 되면 어떤 응답값이 올지 예측이 가능하다.

alias

alias를 사용하는 이유

만약 alias를 쓰지 않고 똑같은 person이라는 대상으로 요청을 해서 응답을 받아올 수 있다고 해도 어떤 person이 내가 기대한 값인지 알지 못하기때문에 별칭으로 구분해줘야한다.

alias 사용하지 않을 경우

fragment(재사용 가능한 단위)

프래그먼트를 사용하면 필드셋을 구성한 다음 필요한 쿼리에 포함시킬 수 있습니다.

사용법

fragment <name> on <대상> {}

사용예제

변수 & query

query PersonInfo($first: Int =1){
  Person1: person(personID: 1) {
    ...personInfo
  }
  Person2: person(personID:2) {
    ...personInfo
  }
}

fragment personInfo on Person {
  filmConnection(first: $first) {
    edges {
      node {
        title
        director
        created
      }
    }
  } 
}

변수

변수를 사용하기 위해서는 다음 세 가지 작업을 해야 합니다.
쿼리는 문자열로 전달된다. index.html -> graphQLFetcher에서 alert 짝어보기
동적으로 쿼리를 조회할 필요가 있음
동적 값을 별도로 전달할 방법인 '변수'제공(기본값 할당 가능)
graphiQL에서는 하단에 query variables 가 있다.

  1. 쿼리안의 정적 값을 $variableName 으로 변경합니다.
  2. $variableName 을 쿼리에서 받는 변수로 선언합니다.
  3. 별도의 전송규약(일반적으로는 JSON) 변수에 variableName: value 을 전달하세요.

작업 타입 /이름

쿼리는 무시할 수 있다. 변수를 넣어주려면 필요
이름을 따로 정의 할수 도 있다

작업 타입 은 쿼리(query), 뮤테이션(mutation), 구독(subscription) 이 될 수 있으며, 어떤 작업의 타입인지를 기술합니다.

query -> 작업 타입 , PersonInfo -> 작업 이름(함수명)

작업 이름 은 의미있고 명시적인 작업의 이름입니다. 디버깅이나 서버 측에서 로깅하는데에 매우 유용 할 수 있습니다. 네트워크 로그나 GraphQL 서버에 문제가 발생하면 내용을 확인하는 대신 코드에서 쿼리 이름을 찾아내는 것이 더 쉽습니다.

지시어
변수를 사용하여 쿼리의 구조와 형태을 동적으로 변경하는 방법이 필요할때 사용한다.
지시어는 필드나 프래그먼트 안에 삽입될 수 있으며 서버가 원하는 방식으로 쿼리 실행에 영향을 줄 수 있습니다.

@include(if: Boolean): 인자가 true 인 경우에만 이 필드를 결과에 포함합니다.
@skip(if: Boolean) 인자가 true 이면 이 필드를 건너뜁니다.

boolean으로 줄때는 항상 기본값을 가지고 있어야한다.

정리

쿼리 -> 요청 , 결과가 동일한 형태, 주석가능, 작업 타입/이름을 줄 수있다.
필드 객체참조하기때문에 다중콜하지않는다. 인자를 넣어 사용, 별칭을 통해서 같은 것을 여러개 구분해서 가져올수았다.

Fragment -> 반복되는 필드셋 / 변수 전달 가능하다.
변수/지시어 -> 동적쿼리방법이다 . @include, @skip이 있다.

뮤테이션

  • 쿼리는 데이터를 가져오는 것이지만 뮤테이션은 데이터를 수정하는 것이다.
  • 변경을 발생시키는 작업이 명시적으로 뮤테이션을 통해 전송되어야한다.

뮤데이션을 연습해보기 위해 아폴로 스튜디오를 통해서 작업해보기!

https://www.apollographql.com/blog/community/backend/8-free-to-use-graphql-apis-for-your-projects-and-demos/

update test

mutation Mutation($where: users_bool_exp!) {
  delete_users(where: $where) {
    returning {
      id
      name
      rocket
      timestamp
    }
  }
}

뮤테이션의 다중 필드
뮤테이션은 쿼리와 마찬가지로 여러 필드를 포함할 수 있습니다. 쿼리와 뮤테이션 사이에 중요한 차이점이 있습니다.

쿼리 필드는 병렬로 실행되지만 뮤테이션 필드는 하나씩 차례대로 실행됩니다.
why? 동시에 일어나면 같은 데이터를 조작하면 에러가 발생할 수 있기 때문에!

op cd

mutation Insert_and_update_users($objects: [users_insert_input!]!, $where: users_bool_exp!, $set: users_set_input) {
  insert_users(objects: $objects) {
    returning {
      id
      name
      rocket
      timestamp
    }
  }
  update_users(where: $where, _set: $set) {
    returning {
      id
      name
      rocket
      timestamp
    }
  }
}

Variables

{
  "objects": [
    {
      "name": "wooks",
      "rocket": "test",
      "id": "4e4fd694-5273-4e9f-885a-f7e7b917b441"
    }
  ],
  "where": {
    "id": {
      "_eq": "4e4fd694-5273-4e9f-885a-f7e7b917b441"
    }
  },
  "set": {
    "name": "sangwooks"
  }
}

response

{
  "data": {
    "insert_users": {
      "returning": [
        {
          "id": "4e4fd694-5273-4e9f-885a-f7e7b917b441",
          "name": "wooks",
          "rocket": "test",
          "timestamp": "2022-03-28T13:28:25.078196+00:00"
        }
      ]
    },
    "update_users": {
      "returning": [
        {
          "id": "4e4fd694-5273-4e9f-885a-f7e7b917b441",
          "name": "sangwooks",
          "rocket": "test",
          "timestamp": "2022-03-28T13:28:25.078196+00:00"
        }
      ]
    }
  }
}

insert 한 즉시 update를 통해 wooks가 sangwooks로 변경
만약 query처럼 병렬로 처리했다면 where에 값이 없을거기 때문에 error가 발생할 수 있다.

inline fragment

GraphQL 스키마에는 인터페이스와 유니온 타입을 정의하는 기능

인터페이스나 유니언 타입을 반환하는 필드를 쿼리하는 경우, 인라인 프래그먼트 을 사용해야한다.

query HeroForEpisode($ep: Episode!) {
  hero(episode: $ep) {
    name
    ... on Droid {
      primaryFunction
    }
    ... on Human {
      height
    }
  }
}

Droid or Human 타입에 따라서 동적으로 요청

meta field

GraphQL 서비스에서 리턴될 타입을 모르는 상황이 발생하면 클라이언트에서 해당 데이터를 처리하는 방법을 결정할 방법이 필요합니다.
GraphQL을 사용하면 쿼리의 어느 지점에서나 메타 필드인 __typename 을 요청하여 그 시점에서 객체 타입의 이름을 얻을 수 있습니다.

{
  search(text: "an") {
    __typename
    ... on Human {
      name
    }
    ... on Droid {
      name
    }
    ... on Starship {
      name
    }
  }
}
{
  "data": {
    "search": [
      {
        "__typename": "Human",
        "name": "Han Solo"
      },
      {
        "__typename": "Human",
        "name": "Leia Organa"
      },
      {
        "__typename": "Starship",
        "name": "TIE Advanced x1"
      }
    ]
  }
}

정리

뮤테이션 -> 데이터의 수정을 가하는 방법
Apollo graphQL -> 다양한 기능이 추가된 라이브러리
뮤테이션 다중 필드 -> 순차 실행(쿼리는 병렬)
인라인 프래그먼트 -> inferface /union 일때 사용

출처

profile
개발자

0개의 댓글