Skip to content
Language:en Author:Laborci Gergely
web-api

GraphQL and RPC: two other API approaches

Objectives

By the end of the lesson, you can say how GraphQL and RPC differ from the resource model of REST, you can read a simple GraphQL query and a JSON-RPC call, and you understand that the choice among the three styles depends on the task.

Why do we need other approaches too?

Not all data exchange is organized around identifiable resources. A mobile screen would like to show the course title, the instructor, and the timetable items at the same time. With a resource-organized API this can be several requests, or the server gives a representation that contains everything (possibly unnecessarily much). In other situations the client asks not for data but for an operation: "start the enrolment". GraphQL gives a natural answer to the first need, RPC to the second. They are not "more advanced" or "outdated" versions of REST, but patterns with a different emphasis.

flowchart LR
    C[Client need] --> R[REST: resource and representation]
    C --> G[GraphQL: field selection in a schema]
    C --> P[RPC: named operation]

GraphQL: naming the wanted fields

The schema of a GraphQL service describes which types and fields can be requested. The client's query selects the needed fields, and the response follows exactly this structure. According to GraphQL's own description, the client can ask for exactly the data it needs, through a strong type system.

A tried example (with version 17.0.2 of the graphql JavaScript library, with in-memory data):

type Oktato { nev: String! }
type Kurzus { id: ID!, cim: String!, ferohely: Int!, oktato: Oktato }
type Query { kurzus(id: ID!): Kurzus }

According to the schema there is a kurzus query, which needs an id. Three requests and the actual responses:

{ kurzus(id: "webprog") { cim oktato { nev } } }
-> {"data":{"kurzus":{"cim":"Webprogramozás 1.","oktato":{"nev":"Minta Péter"}}}}

{ kurzus(id: "webprog") { cim ferohely } }
-> {"data":{"kurzus":{"cim":"Webprogramozás 1.","ferohely":40}}}

{ kurzus(id: "webprog") { cim szinpad } }
-> {"errors":[{"message":"Cannot query field \"szinpad\" on type \"Kurzus\".", ...}]}
  • The first and the second request concern the same resource, but ask for different fields, and receive only those.
  • The third request asks for a field that is not in the schema: the server returns an error before executing anything. The schema is thus part of the contract: the client can request only the supported fields.

GraphQL does not mean that the client runs an arbitrary query directly in the database: the server checks and executes the request according to its own rules. Field selection can help when many kinds of clients work with different data needs. On the other hand, the schema, authorization, performance, and error handling require design. A response coming from a single endpoint is not automatically faster or simpler than every REST resource.

RPC: operations in the center

RPC (Remote Procedure Call) emphasizes the approach in which the client requests a remote, named operation. jelentkezesInditasa ("start enrolment") is conceptually an operation, not the fetching of the representation of a resource. RPC can be a web API working over HTTP, but the principle itself is not tied to a single data format or protocol.

JSON-RPC 2.0 is a simple, public standard for this: the request contains the jsonrpc version, the name of the method, the params parameters, and the id identifier; the response carries either a result or an error field, with the same id. Tried (the trial server knows a single operation):

-> {"jsonrpc":"2.0","method":"jelentkezesInditasa","params":{"hallgato":"h42","kurzus":"webprog"},"id":1}
<- {"jsonrpc":"2.0","result":{"id":1,"ujLetrejott":true},"id":1}

-> (the same call again, id: 2)
<- {"jsonrpc":"2.0","result":{"id":1,"ujLetrejott":false},"id":2}

-> {"jsonrpc":"2.0","method":"mindentTorol","id":3}
<- {"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found"},"id":3}

Three observations:

  • The first call created the enrolment, the second call with the same student and course did not create a new one: the server recognized that it already exists. This is a protection against duplicate enrolment; RPC does not exempt the server from handling a repeated call (2.3).
  • The response can be paired with the request by the id.
  • The unknown operation gets an error: according to the JSON-RPC standard the code -32601 means "Method not found".

(In JSON-RPC the error is in the body of the response; the HTTP status code can be 200 regardless. This differs from REST, where the status code directly signals the result.)

How do we compare them?

REST GraphQL RPC
Starting point resource and HTTP operation schema and field selection named operation
What does the client ask for? the representation of a resource precisely named fields the execution of an operation
Where is the contract? endpoints, methods, status codes the schema the operations and their parameters
A good choice when... the task maps well onto resources many kinds of clients work with different data needs the task is a targeted operation

Real systems also use mixed solutions. A library catalogue fits the resource model well, complex data appearing on many kinds of interfaces can be handled well with GraphQL too, and a targeted application operation can be clear as an RPC. More important than the name of the technology is that the contract is understandable and fits the client's need.

Worked example: the mobile screen of Kurzuspont

The mobile screen needs the course title, its instructor, and the number of free places, but not the timetable.

  • REST: GET /api/kurzusok/webprog returns the whole course object; the instructor can be a separate request, or the server embeds it. Simple, cacheable.
  • GraphQL: the mobile app receives only the three requested fields, in a single request. The schema is well documented, but the server has to manage the complexity of queries.
  • RPC: a kurzusAttekintes ("course overview") operation gives a prepared view. Very targeted, but the operation and the client are more tightly coupled.

Kurzuspont can serve the course data with REST, and the enrolment even with a targeted operation. The choice is a question of the task and the quality of the contract.

Common misconceptions

Statement Clarification
"In GraphQL the client reads the database directly." The client requests data through the schema of the service; the server checks it.
"RPC is the name of a concrete protocol." It is an operation-centered approach; JSON-RPC is a concrete standard.
"GraphQL is always a single fast request." The server's work and the complexity of the data need still count.
"One style is right for every API." The task and the quality of the contract decide.
"With RPC there is no need to think about repetition." Repeating the call must be handled here too (idempotency, 2.3).

In brief

  • GraphQL selects fields from a schema; the response follows the structure of the request.
  • RPC calls a named operation; JSON-RPC is a simple, standard form.
  • The schema, or the description of the operations, is the contract.
  • The choice depends on the client's need and the clarity of the contract, not on fashion.

Review questions

  1. What does the client gain by choosing the fields itself in GraphQL?
  2. What happens if the query asks for a field that is not in the schema?
  3. Why must repeated calls be considered in RPC too?
  4. When would you choose RPC instead of REST?

Learning resources

Prerequisites (2)

  • web API
  • JSON

Teaches (2)

  • GraphQL
  • RPC