Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby를 사용한 GraphQL의 유용한 소개

개발자들이 GraphQL의 경이로움을 찬양하는 것을 들었을 것입니다. 이 시리즈에서 우리는 기술을 사용하여 기술을 배우고자 하며 이 기사에서는 GraphQL을 사용하는 예제 응용 프로그램을 살펴보겠습니다.

GraphQL이란 무엇입니까

GraphQL은 API를 빌드하는 데 사용할 수 있는 쿼리 언어 및 런타임입니다. 개발 스택에서 REST API와 유사한 위치를 유지하지만 더 유연합니다. REST와 달리 GraphQL을 사용하면 클라이언트에서 응답 형식과 콘텐츠를 지정할 수 있습니다. SQL SELECT와 마찬가지로 문을 사용하면 쿼리 결과를 지정할 수 있고 GraphQL에서는 반환된 JSON 데이터 구조를 지정할 수 있습니다. SQL 유추에 따라 GraphQL은 WHERE를 제공하지 않습니다. 절이지만 응답에 대한 데이터를 제공해야 하는 응용 프로그램 개체의 필드를 식별합니다.

GraphQL은 이름에서 알 수 있듯이 애플리케이션이 데이터 그래프인 것처럼 API를 모델링합니다. 이 설명은 애플리케이션을 보는 방식이 아닐 수 있지만 대부분의 시스템에서 사용되는 모델입니다. JSON은 방향성 그래프일 뿐이므로 JSON으로 표현할 수 있는 데이터는 그래프입니다. API를 통해 그래프 모델을 제시하는 애플리케이션이라고 생각하면 GraphQL을 훨씬 더 쉽게 이해할 수 있습니다.

애플리케이션에서 GraphQL 사용

개요에서 GraphQL에 대해 설명했으므로 이제 데이터 모델 또는 그래프의 정의부터 시작하여 GraphQL을 사용하는 응용 프로그램을 실제로 빌드해 보겠습니다. 작년에 나는 새로운 취미를 얻었다. 저는 일렉트릭 업라이트 베이스를 연주하는 법과 일반적인 음악에 대해 배우고 있기 때문에 데모 앱을 만들 때 음악과 관련된 예가 떠올랐습니다.

예의 개체 유형은 아티스트입니다. 및 노래 . 아티스트 여러 노래 보유 및 노래 아티스트와 연결됨 . 각 개체 유형에는 name과 같은 속성이 있습니다. .

API 정의

GraphQL은 GraphQL 사양에서 "유형 시스템 정의 언어"라고도 하는 SDL(스키마 정의 언어)을 사용합니다. GraphQL 유형은 이론상 모든 언어로 정의할 수 있지만 가장 일반적인 불가지론 언어는 SDL이므로 SDL을 사용하여 API를 정의하겠습니다.

type Artist {
  name: String!
  songs: [Song]
  origin: [String]
}

type Song {
  name: String!
  artist: Artist
  duration: Int
  release: String
}

아티스트 name이(가) 있습니다. 그것은 String입니다 . 느낌표는 필드가 non-null임을 의미합니다. . songs 노래의 배열입니다. 개체 및 origin 이것은 String입니다. 정렬. 노래 비슷하지만 하나의 홀수 필드가 있습니다. release 필드는 시간 또는 날짜 유형이어야 하지만 GraphQL에는 해당 유형이 핵심 유형으로 정의되어 있지 않습니다. 서로 다른 GraphQL 구현 간의 완전한 이식성을 위해 String 사용. 우리가 사용할 GraphQL 구현에는 Time이 있습니다. 유형이 추가되었으므로 노래를 변경해 보겠습니다. release 필드는 Time입니다. 유형. 반환된 값은 String입니다. , 그러나 유형을 Time으로 설정하여 API를 더 정확하게 문서화합니다.

  release: Time

마지막 단계는 하나 이상의 객체를 얻는 방법을 설명하는 것입니다. 이를 루트라고 하며 쿼리의 경우 쿼리 루트라고 합니다. 루트에는 artist라는 필드 또는 메서드가 하나만 있습니다. 아티스트 name이(가) 필요합니다. .

type Query {
  artist(name: String!): Artist
}

응용 프로그램 작성

응용 프로그램에서 이것을 어떻게 사용하는지 살펴보겠습니다. Ruby용 GraphQL 서버에는 여러 가지 구현이 있습니다. 일부 접근 방식에서는 위의 SDL을 Ruby에 상응하는 것으로 변환해야 합니다. 제가 구축한 HTTP 서버인 Agoo는 SDL 정의를 그대로 사용하고 Ruby 코드는 플레인 바닐라 Ruby이므로 그대로 사용하겠습니다.

Ruby 클래스는 GraphQL 유형과 일치합니다. Ruby 클래스 이름이 GraphQL 유형 이름과 일치하도록 함으로써 불필요한 복잡성을 추가하지 않습니다.

class Artist
  attr_reader :name
  attr_reader :songs
  attr_reader :origin
 
  def initialize(name, origin)
    @name = name
    @songs = []
    @origin = origin
  end
 
  # Only used by the Song to add itself to the artist.
  def add_song(song)
    @songs << song
  end
end
 
class Song
  attr_reader :name     # string
  attr_reader :artist   # reference
  attr_reader :duration # integer
  attr_reader :release  # time
 
  def initialize(name, artist, duration, release)
    @name = name
    @artist = artist
    @duration = duration
    @release = release
    artist.add_song(self)
  end
end

메소드는 Ruby 클래스의 필드와 일치합니다. 메서드에는 인수가 없거나 args={}가 없습니다. . 이것이 GraphQL API가 기대하는 것이며 여기에서의 구현은 적합합니다. initialize 메서드는 곧 보게 될 예제의 데이터를 설정하는 데 사용됩니다.

쿼리 루트 클래스도 정의해야 합니다. artist 참고 SDL Query와 일치하는 메소드 루트 유형. attr_reader artist용 도 추가되었습니다. Query에 해당 필드를 추가하기만 하면 API에 노출됩니다. SDL 문서를 입력하십시오.

class Query
  attr_reader :artists
 
  def initialize(artists)
    @artists = artists
  end
 
  def artist(args={})
    @artists[args['name']]
  end
end

GraphQL 루트(쿼리 루트와 혼동하지 말 것)는 쿼리 루트 위에 있습니다. GraphQL은 선택적으로 세 개의 필드를 갖도록 정의합니다. 이 경우 Ruby 클래스는 query를 구현합니다. 필드. 초기화 프로그램은 내가 즐겨 듣는 뉴질랜드 인디 밴드의 데이터를 로드합니다.

class Schema
  attr_reader :query
  attr_reader :mutation
  attr_reader :subscription
 
  def initialize()
    # Set up some data for testing.
    artist = Artist.new('Fazerdaze', ['Morningside', 'Auckland', 'New Zealand'])
    Song.new('Jennifer', artist, 240, Time.utc(2017, 5, 5))
    Song.new('Lucky Girl', artist, 170, Time.utc(2017, 5, 5))
    Song.new('Friends', artist, 194, Time.utc(2017, 5, 5))
    Song.new('Reel', artist, 193, Time.utc(2015, 11, 2))
    @artists = {artist.name => artist}
 
    @query = Query.new(@artists)
  end
end

최종 설정은 구현에 따라 다릅니다. 여기서 서버는 /graphql에 대한 핸들러를 포함하도록 초기화됩니다. HTTP 요청 경로를 입력하고 시작합니다.

Agoo::Server.init(6464, 'root', thread_count: 1, graphql: '/graphql')
Agoo::Server.start()

그런 다음 GraphQL 구현은 이전에 정의된 SDL($songs_sdl ) 그런 다음 서버가 요청을 처리하는 동안 애플리케이션이 절전 모드로 전환됩니다.

Agoo::GraphQL.schema(Schema.new) {
  Agoo::GraphQL.load($songs_sdl)
}
sleep

이 예제의 코드는 GitHub에서 찾을 수 있습니다.

API 사용

API를 테스트하려면 웹 브라우저, Postman 또는 curl을 사용할 수 있습니다. .

이를 시도할 GraphQL 쿼리는 다음과 같습니다.

{
  artist(name:"Fazerdaze") {
    name
    songs{
      name
      duration
    }
  }
}

쿼리는 아티스트를 요청합니다. Fazerdaze라는 이름의 name을 반환합니다. 및 songs JSON 문서에서. 각 노래에 대해 nameduration 노래 JSON 객체로 반환됩니다. 출력은 다음과 같아야 합니다.

{
  "data": {
    "artist": {
      "name": "Fazerdaze",
      "songs": [
        {
          "name": "Jennifer",
          "duration": 240
        },
        {
          "name": "Lucky Girl",
          "duration": 170
        },
        {
          "name": "Friends",
          "duration": 194
        },
        {
          "name": "Reel",
          "duration": 193
        }
      ]
    }
  }
}

쿼리에서 선택적 공백을 제거한 후 curl로 만든 HTTP GET은 해당 내용을 반환해야 합니다.

curl -w "\n" 'localhost:6464/graphql?query=\{artist(name:"Fazerdaze")\{name,songs\{name,duration\}\}\}&indent=2'

쿼리를 변경하고 duration을 바꾸십시오. release Ruby Time이 JSON 문자열로 변환된 것을 확인하세요.

노래의 아웃트로

우리는 GraphQL을 가지고 노는 것을 즐겼고 여러분이 함께 태그를 지정하고 그 과정에서 무언가를 배웠기를 바랍니다. 감사합니다, 당신은 훌륭한 청중이었습니다. Ruby에 대해 더 이야기하고 싶다면 바에서 상품을 판매하겠습니다.