The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
GraphQL is a data “query language created by Facebook in 2015 for describing the capabilities and requirements of data models for client‐server applications”. The GraphQL specification can be read on their hosted GitHub. A cliff notes version is described on GraphQL’s GitHub. To learn more about the GraphQL language, I highly recommend GraphQL’s website.
This package pulls inspiration from graphql-js and Mathew Mueller’s graph.ql. I wanted the full functionality of GraphQL, but I didn’t want to force users to write full object definitions when can already be defined with GraphQL syntax.
gqlr
merges R’s rapid development speed with the
consistent query language of GraphQL.
# The development version from GitHub:
# install.packages("devtools")
::install_github("schloerke/gqlr") devtools
If you encounter a clear bug, please file a minimal reproducible example on GitHub.
```{r, message = FALSE}
library(magrittr) library(gqlr)
schema <- ” type Hello { world: String } schema { query: Hello } ” %>% gqlr_schema()
execute_request(“{world}”, schema, initial_value = list(world = “Hi!”)) # { # “data”: { # “world”: “Hi!” # } # }
### Star Wars
#### Star Wars Data
```r
add_human <- function(human_data, id, name, appear, home, friend) {
human <- list(id = id, name = name, appearsIn = appear, friends = friend, homePlanet = home)
# set up a function to be calculated if the field totalCredits is required
human$totalCredits <- function(obj, args, schema) {
length(human$appearsIn)
}
human_data[[id]] <- human
human_data
}
add_droid <- function(droid_data, id, name, appear, pf, friend) {
droid <- list(id = id, name = name, appearsIn = appear, friends = friend, primaryFunction = pf)
# set extra fields manually
droid$totalCredits <- length(droid$appearsIn)
droid_data[[id]] <- droid
droid_data
}
human_data <- list() %>%
add_human("1000", "Luke Skywalker", c(4, 5, 6), "Tatooine", c("1002", "1003", "2000", "2001")) %>%
add_human("1002", "Han Solo", c(4, 5, 6), "Corellia", c("1000", "1003", "2001")) %>%
add_human("1003", "Leia Organa", c(4, 5, 6), "Alderaan", c("1000", "1002", "2000", "2001"))
droid_data <- list() %>%
add_droid("2000", "C-3PO", c(4, 5, 6), "Protocol", c("1000", "1002", "1003", "2001")) %>%
add_droid("2001", "R2-D2", c(4, 5, 6), "Astromech", c("1000", "1002", "1003"))
all_characters <- list() %>% append(human_data) %>% append(droid_data)
all_characters[[1]]
# $id
# [1] "1000"
#
# $name
# [1] "Luke Skywalker"
#
# $appearsIn
# [1] 4 5 6
#
# $friends
# [1] "Tatooine"
#
# $homePlanet
# [1] "1002" "1003" "2000" "2001"
#
# $totalCredits
# function (obj, args, schema)
# {
# length(human$appearsIn)
# }
# <environment: 0x7fadd8ca2038>
"
enum Episode { NEWHOPE, EMPIRE, JEDI }
interface Character {
id: String!
name: String
friends: [Character]
appearsIn: [Episode]
}
type Droid implements Character {
id: String!
name: String
friends: [Character]
appearsIn: [Episode]
primaryFunction: String
}
type Human implements Character {
id: String!
name: String
friends: [Character]
appearsIn: [Episode]
homePlanet: String
}
type Query {
hero(episode: Episode): Character
human(id: String!): Human
droid(id: String!): Droid
}
# the schema type must be provided if a query or mutation is to be executed
schema {
query: Query
}
" %>%
gqlr_schema(
Episode = list(
resolve = function(episode_id, schema) {
switch(as.character(episode_id),
"4" = "NEWHOPE",
"5" = "EMPIRE",
"6" = "JEDI",
"UNKNOWN_EPISODE"
)
}
),Character = list(
resolve_type = function(id, schema) {
ifelse(id %in% names(droid_data), "Droid", "Human")
}
),Human = list(
# Add a resolve method for type Human that takes in an id and returns the human data
resolve = function(id, args, schema) {
human_data[[id]]
}
),Droid = list(
# description for Droid
description = "A mechanical creature in the Star Wars universe.",
# Add a resolve method for type Droid that takes in an id and returns the droid data
resolve = function(id, schema) {
droid_data[[id]]
}
),Query = function(null, schema) {
list(
# return a function for key 'hero'
# the id will be resolved by the appropriate resolve() method of Droid or Human
hero = function(obj, args, schema) {
<- args$episode
episode if (identical(episode, 5) || identical(episode, "EMPIRE")) {
"1000" # Luke
else {
} "2001" # R2-D2
}
},# the id will be resolved by the Human resolve() method
human = function(obj, args, schema) {
$id
args
},# the id will be resolved by the Droid resolve() method
droid = function(obj, args, schema) {
$id
args
}
)
}->
) star_wars_schema
# Use the resolve method to initialize the data
"
{
hero {
id
name
friends {
id
name
}
}
}
" %>%
execute_request(star_wars_schema)
# {
# "data": {
# "hero": {
# "id": "2001",
# "name": "R2-D2",
# "friends": [
# {
# "id": "1000",
# "name": "Luke Skywalker"
# },
# {
# "id": "1002",
# "name": "Han Solo"
# },
# {
# "id": "1003",
# "name": "Leia Organa"
# }
# ]
# }
# }
# }
# Use variables...
"
query FetchSomeIDQuery($someId: String!) {
human(id: $someId) {
name
}
}
" %>%
execute_request(star_wars_schema, variables = list(someId = "1000"))
# {
# "data": {
# "human": {
# "name": "Luke Skywalker"
# }
# }
# }
# Introspection
"
query IntrospectionTypeQuery {
__type(name: \"Droid\") {
kind
name
fields {
name
}
}
}
" %>%
execute_request(star_wars_schema)
# {
# "data": {
# "__type": {
# "kind": "OBJECT",
# "name": "Droid",
# "fields": [
# {
# "name": "id"
# },
# {
# "name": "name"
# },
# {
# "name": "friends"
# },
# {
# "name": "appearsIn"
# },
# {
# "name": "primaryFunction"
# },
# {
# "name": "__typename"
# }
# ]
# }
# }
# }
# R
:::server(star_wars_schema, log = TRUE) # forgot to export gqlr
Explore with curl
# GET R2-D2 and his friends' names
curl '127.0.0.1:8000/graphql?query=%7Bhero%7Bname%7D%7D&pretty=TRUE'
# {
# "data": {
# "hero": {
# "name": "R2-D2"
# }
# }
# }
# POST for R2-D2 and his friends' names (no need to url escape the query)
curl --data '{"query":"{hero{name}}"}' '127.0.0.1:8000/graphql' # defaults to parse as JSON
# {"data":{"hero":{"name":"R2-D2"}}}
curl --data '{"query":"{hero{name}}"}' '127.0.0.1:8000/graphql' --header "Content-Type:application/json"
# {"data":{"hero":{"name":"R2-D2"}}}
curl --data '{hero{name}}' '127.0.0.1:8000/graphql' --header "Content-Type:application/graphql"
# {"data":{"hero":{"name":"R2-D2"}}}
# GET Schema definition
curl '127.0.0.1:8000/'
# enum Episode {
# NEWHOPE
# EMPIRE
# JEDI
# }
#
# type Droid implements Character {
# id: String!
# name: String
# friends: [Character]
# appearsIn: [Episode]
# primaryFunction: String
# }
#
# type Human implements Character {
# id: String!
# name: String
# friends: [Character]
# appearsIn: [Episode]
# homePlanet: String
# }
#
# type Query {
# hero(episode: Episode): Character
# human(id: String!): Human
# droid(id: String!): Droid
# }
#
# interface Character {
# id: String!
# name: String
# friends: [Character]
# appearsIn: [Episode]
# }
#
# schema {
# query: Query
# }
WOMBAT2016 in Melbourne, Australia; Feb 2016.
gqlr
uses this package to parse all requests strings
and schema strings into jsonghql
client could be used to submit requests to
gqlr
server to be executedThese binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.