http://api.mysite.com/v2/meetups
http://api.mysite.com/v2/meetups/12
http://api.mysite.com/v2/meetups/attendees
http://api.mysite.com/v2/meetups/attendees/13
GET http://api.mysite.com/v2/meetups/12
{
"meetup": {
"id": 12
"name": "Dead Man's Chest"
"date": "20170221T123446Z"
"attendeesIds": [
123,
12
223
21
]
}
}
GET http://api.mysite.com/v3/meetups/12
{
"meetup": {
"id": 12
"name": "Dead Man's Chest"
"date": "20170221T123446Z"
"attendees": [
{
"id": 123
"name": "Vassilis"
},
{
"id": 12
"name": "George"
}
]
}
}
{
"data": {
... what you asked for ...
}
"errors": [
{
"message": "blah"
}
]
}
// Request
{
attendee {
id
name
}
}
// Response
{
"data": {
"attendee": {
"id": 12
"name": "Vassilis"
}
}
}
// Request
{
attendee {
id
name
birthdate
}
}
// Response
{
"data": {
"attendee": {
"id": 12
"name": "Vassilis"
"birthdate": "20170221T123446Z"
}
}
}
// Request
{
member(id: "12") {
id
name
birthday(type: FORMATTED)
}
}
// Response
{
"data": {
"member": {
"id": 12
"name": "Vassilis"
"birthdate": "13 Jan 1986"
}
}
}
enum argument! Much Wow!
// Request
{
attendee: member(id: "12") {
id
fullname: name
birthday(type: FORMATTED)
}
}
// Response
{
"data": {
"attendee": {
"id": 12
"fullname": "Vassilis"
"birthdate": "13 Jan 1986"
}
}
}
// Request
{
meetup {
id
name
location
start_date
end_date
rsvp_url
cover_photo {
url
size
}
}
}
// Request
{
meetup {
...MeetupDetails
}
}
fragment MeetupDetails on Meetup {
id
name
location
start_date
end_date
rsvp_url
cover_photo {
url
size
}
}
// Request
query GetMeetupByStartDate($start_date: Date) {
meetup(start_date: $start_date) {
id
name
location
}
}
{
"start_date": "2017-02-21T16:42:34+00:00"
}
// Response
{
"data": {
"id": 1,
"name": "Dead Man's chest",
"location": "Coho"
}
}
Operation Name
Useful for debugging stuff on the server side
// Request
query CreateMeetup($name: String!, location: String!, $start_date: Date) {
createMeetup(name: $name, location: $location, start_date: $start_date){
id
}
}
{
"name": "The Return of the Mummy",
"location": "OK!Thess"
}
// Response
{
"data": {
"id": 100
}
}
If the type name has no "!", it's optional
$start_date can be omitted from the mutation
DEMO
The traditional way
struct GraphQL {
static func getAttendee(id: String) {
return "query {" +
" attendee(id: \"\(id)\") {" +
" id" +
" name" +
" birthdate" +
" }"+
"}"
}
}
// ... feed it in an Alamofire GET request
final class Attendee: NSObject, ResponseObjectSerializable {
let id: String?
let name: String?
let birthdate: Date?
init?(representation: AnyObject) {
id = representation.value(forKeyPath: "id") as? String
name = representation.value(forKeyPath: "name") as? String
birthdate = representation.value(forKeyPath: "birthdate") as? Date
}
}
The traditional way
The traditional way
The shiny new toy
A strongly-typed, caching GraphQL client for iOS, written in Swift.
APOLLO
1. Download your schema
apollo-codegen download-schema http://localhost:8080/graphql --output schema.json
2. Add a build phase to your project
$APOLLO_FRAMEWORK_PATH/check-and-run-apollo-codegen.sh \
generate $(find . -name '*.graphql') \
--schema schema.json \
--output API.swift
3. Define your queries & mutations in .graphql files
4. Build and enjoy
APOLLO
// In Queries.graphql
query GetAttendee {
attendee {
id
name
birthdate
}
}
// In your API class
apollo.fetch(query: GetAttendee()) { (result, error) in
print(result?.data?.attendee?.name) // Vassilis
}