SENG3011

🌿  2.4 - Advanced Data Interchange

In this lecture

  • What is GraphQL?
  • What is gRPC?
  • Trade-offs of using GraphQL and gRPC

Problems with REST

  • Over-fetching/under-fetching - when an endpoint provides more or less data than a client needs
    • REST APIs have a fixed structure
    • We often either fetch more data than we actually need, or need to make calls to multiple endpoints to fulfil our needs
  • No type system - no assurance on types in request/response - easier for bugs to creep in
  • Performance - slow to send JSON across the wire

gRPC - gRPC Remote Procedure Calls

  • Fundamental idea - a client application can directly call a method on a server application on a different machine as if it were a local object
  • Designed for building distributed applications
  • Based around the idea of defining a service, specifying a series of methods that can be called remotely with parameters and return types
  • Server side implements the interface and runs a gRPC server to handle client calls
  • Client side has a stub that provides the same methods
  • Useful for service-to-service communication

Protocol Buffers

  • A mature open source mechanism for serialising data
  • Define data structure to serialise in a .proto file
  • Use protocol buffer compiler protoc to generate data access classes in preferred languages from proto definition
  • Data access classes provide simple getters/setters, methods to serialise/parse the string from raw bytes
  • Save time and space on the wire, sending serialised bytes instead of sending a raw JSON string

Protocol Buffers

message Person {
  string name = 1;
  int32 id = 2;
  bool has_ponycopter = 3;
}

Defining a gRPC API

// The greeter service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

gRPC: Trade-offs

  • Pros
    • Big performance gain via compared data format, fast message encoding/decoding and use of HTTP/2
    • Better security with TLS/SSL
  • Cons
    • Need to use tools to analyse payloads and perform debugging
    • Limited browser support - difficult to use in customer-facing web applications

GraphQL

  • A query language for APIs and a runtime for fulfilling those queries with your existing data
  • SQL for Web APIs!
  • Developed by Facebook
  • Useful for public-facing APIs

Making a Query

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

Parent and child fields

{
  hero {
    name
    friends {
      name
    }
  }
}
{
  "data": {
    "hero": {
      "name": "R2-D2",
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  }
}

Fragments

{
  leftComparison: hero(episode: EMPIRE) {
    ...comparisonFields
  }
  rightComparison: hero(episode: JEDI) {
    ...comparisonFields
  }
}

fragment comparisonFields on Character {
  name
  appearsIn
  friends {
    name
  }
}
{
  "data": {
    "leftComparison": {
      "name": "Luke Skywalker",
      "appearsIn": [
        "NEWHOPE",
        "EMPIRE",
        "JEDI"
      ],
      "friends": [
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        },
        {
          "name": "C-3PO"
        },
        {
          "name": "R2-D2"
        }
      ]
    },
  }
}

A full query

query HeroNameAndFriends($episode: Episode) {
  hero(episode: $episode) {
    name
    friends {
      name
    }
  }
}
{
  "data": {
    "hero": {
      "name": "R2-D2",
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  }
}
{
  "episode": "JEDI"
}

Mutations

mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}
{
  "data": {
    "createReview": {
      "stars": 5,
      "commentary": "This is a great movie!"
    }
  }
}
{
  "ep": "JEDI",
  "review": {
    "stars": 5,
    "commentary": "This is a great movie!"
  }
}

Types and Interfaces

type Character {
  name: String!
  appearsIn: [Episode!]!
}
interface Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
}
type Human implements Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
  starships: [Starship]
  totalCredits: Int
}

GraphQL Servers and Clients

  • GraphQL server consists of a predefined schema
  • Languages define a library to create GraphQL servers and resolve queries
  • Need to define a series of resolvers/data fetchers to form an API layer
  • Different GraphQL clients have different specialisations and use cases

Pagination

  • How do we deal with large volumes of continuous data?
  • Seperate data into "pages" - pagination
  • Need to keep track of start/end of each page
{
  user(id: "ZW5jaG9kZSBIZWxsb1dvcmxk") {
    id
    name
    friendsConnection(first: 3) {
      edges {
        cursor
        node {
          id
          name
        }
      }
    }
  }
}

The Graph in GraphQL

The Graph in GraphQL

Defining connections, edges and nodes in the graph

type UserFriendsConnection {
  pageInfo: PageInfo!
  edges: [UserFriendsEdge]
}

type UserFriendsEdge {
  cursor: String!
  node: User
}
type User {
  id: ID!
  name: String
  friendsConnection(
    first: Int,
    after: String,
    last: Int,
    before: String
  ): UserFriendsConnection
}

GraphQL: Trade-offs

  • Pros
    • Autogenerates documentation and allows for straightforward API versioning
    • Leads to better performance, since there's no over/under fetching
    • Consolidates scattered APIs under a single endpoint
  • Cons
    • Harder to setup, more overhead
    • Caching implementations more difficult

Common Architectural Patterns

Further Reading

  • GraphQL connections https://www.apollographql.com/blog/graphql/explaining-graphql-connections/ 
  • GraphQL info https://graphql.org/learn/
  • Rest vs GraphQL vs gRPC https://www.baeldung.com/rest-vs-graphql-vs-grpc
  • How to use GraphQL with Postman https://www.baeldung.com/graphql-postman
  • gRPC Info https://grpc.io/docs/

SENG3011 23T1 - 2.4 - Advanced Data Interchange

By npatrikeos

SENG3011 23T1 - 2.4 - Advanced Data Interchange

  • 205