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
- What does the client gain by choosing the fields itself in GraphQL?
- What happens if the query asks for a field that is not in the schema?
- Why must repeated calls be considered in RPC too?
- When would you choose RPC instead of REST?
Learning resources
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
graphqlJavaScript 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
kurzusquery, which needs anid. Three requests and the actual responses: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
jsonrpcversion, the name of themethod, theparamsparameters, and theididentifier; the response carries either aresultor anerrorfield, with the sameid. Tried (the trial server knows a single operation):Three observations:
id.-32601means "Method not found".(In JSON-RPC the error is in the body of the response; the HTTP status code can be
200regardless. This differs from REST, where the status code directly signals the result.)How do we compare them?
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.
GET /api/kurzusok/webprogreturns the whole course object; the instructor can be a separate request, or the server embeds it. Simple, cacheable.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
In brief
Review questions
Learning resources