在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):contentful-labs/gqli.rb开源软件地址(OpenSource Url):https://github.com/contentful-labs/gqli.rb开源编程语言(OpenSource Language):Ruby 100.0%开源软件介绍(OpenSource Introduction):GQLi - GraphQL Client for humansGQLi is a DSL (Domain Specific Language) to consume GraphQL APIs.
InstallationInstall it via the command line: gem install gqli Or add it to your gem 'gqli' UsageCreating a GraphQL ClientFor the examples throughout this README, we'll be using the Contentful and Github GraphQL APIs, for which we have factory methods. Therefore, here's the initialization code required for both of them: require 'gqli'
# Creating a Contentful GraphQL Client
SPACE_ID = 'cfexampleapi'
CF_ACCESS_TOKEN = 'b4c0n73n7fu1'
CONTENTFUL_GQL = GQLi::Contentful.create(SPACE_ID, CF_ACCESS_TOKEN)
# Creating a Github GraphQL Client
GITHUB_ACCESS_TOKEN = ENV['GITHUB_TOKEN']
GITHUB_GQL = GQLi::Github.create(GITHUB_ACCESS_TOKEN) Note: Please feel free to contribute factories for your favorite GraphQL services. For creating a custom GraphQL client: require 'gqli'
# Create a custom client
GQL_CLIENT = GQLi::Client.new(
"https://graphql.yourservice.com",
headers: {
"Authorization" => "Bearer AUTH_TOKEN"
}
) Creating a QueryQueries are the way to request data from a GraphQL API. This gem provides a simple DSL to create your own queries. The query operator is # Query to fetch the usernames for the first 10 watchers of the first 10 repositories I belong to
WatchersQuery = GQLi::DSL.query {
viewer {
login
repositories(first: 10) {
edges {
node {
nameWithOwner
watchers(first: 10) {
edges {
node {
login
}
}
}
}
}
}
}
} Divide and conquer - using FragmentsIn order to reuse parts of queries, we can split chunks of our queries into Fragments. The fragment operator is To include fragments within other nodes, use the To do type matching, use the # Base fragment that will be reused for all Cat queries.
CatBase = GQLi::DSL.fragment('CatBase', 'Cat') {
name
likes
lives
}
CatBestFriend = GQLi::DSL.fragment('CatBestFriend', 'Cat') {
bestFriend {
# Here, because `bestFriend` is polimorphic in our GraphQL API,
# we need to explicitly state for which Type we want to include our fragment.
# To do a type match, instead of GraphQLs `... on SomeType` we do `__on('SomeType')`.
__on('Cat') {
# To include a fragment, instead of GraphQLs `...`, we use `___`.
___ CatBase
}
}
}
# A fragment reusing multiple fragments
CatImportantFields = GQLi::DSL.fragment('CatImportantFields', 'Cat') {
___ CatBase
___ CatBestFriend
}
# A fragment used to define a query, alongside other regular fields.
CatQuery = GQLi::DSL.query {
catCollection(limit: 1) {
items {
___ CatImportantFields
image {
url
}
}
}
} Executing the queriesTo execute the queries, you need to pass a For example: response = CONTENTFUL_GQL.execute(CatQuery)
puts "Query sent:"
puts response.query.to_gql
puts
puts "Response received"
response.data.catCollection.items.each do |c|
puts "Name: #{c.name}"
puts "Likes: #{c.likes.join(", ")}"
puts "Lives #: #{c.lives}"
c.bestFriend.tap do |bf|
puts "Best Friend:"
puts "\tName: #{bf.name}"
puts "\tLikes: #{bf.likes.join(", ")}"
puts "\tLives #: #{bf.lives}"
end
end The output is:
Schema Introspection and ValidationBy default this library will fetch and cache a copy of the GraphQL Schema for any API you create a client for. This schema is used for query validation before running queries against the APIs. In case a query is invalid for the given schema, an exception will be raised. To disable schema caching completely, when you initialize your client, send Queries executed using the To avoid validating a query, you can use To validate the query outside of the scope of an HTTP request, you can use Embedding the DSL in your classesIf you want to avoid the need for prepending all GQLi DSL's calls with class ContentfulClient
extend GQLi::DSL # Makes DSL available at a class level
include GQLi::DSL # Makes DSL available at an object level
SPACE_ID = 'cfexampleapi'
ACCESS_TOKEN = 'b4c0n73n7fu1'
CONTENTFUL_GQL = GQLi::Client.new(
"https://graphql.contentful.com/content/v1/spaces/#{SPACE_ID}",
headers: { "Authorization" => "Bearer #{ACCESS_TOKEN}" }
)
CatBase = fragment('CatBase', 'Cat') {
name
likes
lives
}
CatBestFriend = fragment('CatBestFriend', 'Cat') {
bestFriend {
__on('Cat') {
___ CatBase
}
}
}
CatImportantFields = fragment('CatImportantFields', 'Cat') {
___ CatBase
___ CatBestFriend
}
def cats(limit)
CONTENTFUL_GQL.execute(
query {
catCollection(limit: limit) {
items {
___ CatImportantFields
image {
url
}
}
}
}
)
end
end
response = ContentfulClient.new.cats(5) Dealing with name collisionsBy defining queries via a DSL, you may sometimes find that the fields you query for are also the names of built-in methods or reserved keywords of the language. To avoid collisions you can use the query = GQLi::DSL.query {
catCollection {
items {
sys {
__node('id')
}
}
}
} The helper method query = GQLi::DSL.query {
__node('catCollection', limit: 5) {
items {
name
}
}
} DirectivesIn GraphQL, nodes can be selectively included or removed by the usage of directives, there are 2 directives available for the querying specification to do this: query = GQLi::DSL.query {
someNode(:@include => {if: object.includes_some_node?})
} This will get transformed to: query {
someNode @include(if: true) # or false
} This behaviour is equivalent to using native Ruby to include/exclude a field from the query: query = GQLi::DSL.query {
someNode if object.includes_some_node?
} The difference is that by using the native implementation, in case of the condition not being met, the node will be completely not included in the outgoing query. EnumsEnums are a list of predefined values that are defined on the type system level.
Since Ruby doesn't have built-in Enums that can be translated directly into GraphQL Enums, we created the query = GQLi::DSL.query {
catCollection(order: __enum('lives_ASC')) {
items {
name
}
}
} This will render to: query {
catCollection(order: lives_ASC) {
items {
name
}
}
} AliasesThere may be times where it is useful to have parts of the query aliased, for example, when querying for This can be accomplished as follows: ArticleFragment = GQLi::DSL.fragment('ArticleFragment', 'ArticleCollection') {
items {
title
description
heroImage {
url
}
}
}
query = GQLi::DSL.query {
__node('pinned: articleCollection', where: {
sys: { id_in: ['articleID'] }
}) {
___ ArticleFragment
}
__node('unpinned: articleCollection', where: {
sys: { id_not_in: ['articleID'] }
}) {
___ ArticleFragment
}
} Get involvedWe appreciate any help on our repositories. LicenseThis repository is published under the MIT license. Code of ConductWe want to provide a safe, inclusive, welcoming, and harassment-free space and experience for all participants, regardless of gender identity and expression, sexual orientation, disability, physical appearance, socioeconomic status, body size, ethnicity, nationality, level of experience, age, religion (or lack thereof), or other identity markers. Read our full Code of Conduct. |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论