Go API's: REST & GraphQL
John Machahuay Giraldo
About me
- Full Stack developer
- Originally a Web developer, now doing both web and mobile development
- Now building an app for IOS and android with React Native
- Speaker in meetups.
REST
- REST (REpresentational State Transfer)
- Defined in 2000 by Roy Fielding, who was the main coautor of the especification of HTTP.
- HTTP Verbs
- Resources based on URLS - endpoints
- Resources are the information that you want to access, modify, delete independently of the format.
- A representation is a machine readable explanation of the current state of a resource.
REST
/users/7/
getUserById(7) responds ->
user: {
"email": "johndoe@mailinator.com",
"username", "john doe"
}
/users/7/organizations
getOrganizationsByUser(7) responds ->
organizations: {
organizations: [
{"name": "Org1"}, {"name": "Org2"}
]
}
then display a list of organizations based on the user
REST
- Define and specify precisely the data you want adding many endpoints.
- Expose a suite of URLs each of which expose a single resource.
- Any change can be considered a breaking change, and breaking changes require a new version.
- This has lead to a common practice of always avoiding breaking changes and serving a versionless API.
- Postman for testing API REST.
GraphQL
GraphQL is a new way to think about building and querying APIs. Rather than construct several REST requests to fetch data that you're interested in, you can often make a single call to fetch the information you need.
GraphQL Query
{ user(id: 1564) { name, email } }
Sample response
{ "data": { "user": { "name": "Dan", "email": "dan@company.com" } } }
GraphQL
GraphQL is, above all, a querying language, and the format of the query you send matches the data you receive. For example, given the following query:
{
viewer {
login
bio
organizations(first: 3) {
edges {
org:node {
name
}
}
}
}
}
{
"data": {
"viewer": {
"login": "gjtorikian",
"bio": "I inhale and exhale.",
"organizations": {
"edges": [
{
"org": {
"name": "GitHub"
}
},
{
"org": {
"name": "Atom"
}
}
]
}
}
}
}
GraphQL Query
{ user(id: 1564) { name, email, friends { id, name } } }
Sample response
{ "data": { "user": { "name": "Dan", "email": "dan@company.com", "friends": [ { "id": 1056, "name": "Marie" }, { "id": 1232, "name": "Bob" } ] } } }
GraphQL Query
{ user(id: 1564) { name, email, friends { id } } }
Sample response
{ "data": { "user": { "name": "Dan", "email": "dan@company.com", "friends": [ { "id": 1056 }, { "id": 1232 } ] } } }
Client view
{ user (id:1313) { name, email, portfolio: { id, description, items: { id, title } } } }
Graphql query
How Graphql works
Backend
Client view
loadUserById
loadPortfolioById
loadItemsByPortfolioId
{ user (id:1313) { name, email, portfolio: { id, description, items: { id, title } } } }
Graphql query
How Graphql works
Backend
Client view
loadUserById
loadPortfolioById
loadItemsByPortfolioId
{ user (id:1313) { name, email, portfolio: { id, description, items: { id, title } } } }
Graphql query
How Graphql works
Backend
Mongo with users
SQL with portfolios
Whatever API
Client view
loadUserById
loadPortfolioById
loadItemsByPortfolioId
{ user (id:1313) { name, email, portfolio: { id, description, items: { id, title } } } }
Graphql query
How Graphql works
Backend
Mongo with users
SQL with portfolios
Whatever API
... it also can be a "changing" query
Client view
loadUserById
loadPortfolioById
loadItemsByPortfolioId
{ user (id:1313) { name, email, portfolio: { id, description, items: { id, title } } } }
{ data: { user: { name: 'John', email: 'john@doe.com', portfolio: { id: 33545232, description: 'Best portfolio...', items: [ { id: 231232, title: 'first item' }, { id: 545444, title: 'best website' } ] } } } }
Graphql query
JSON response
How Graphql works
Backend
GraphQL is:
- Declarative (client declares what he needs)
- Hierarchical (nestings...)
- Strongly-typed (int, string, array...)
- No data overfetching (and backward compatibility)
- Product-centric (client app is the product)
- Application-Layer Protocol (json, xml, http, sql, ...)
- Introspective (documentation = schema)
GraphQL vs REST
REST
GraphQL
is an approach
is a protocol
- is it RESTful or not?
- often "non-rest" decisions
- everyone feels guilty
What is?
REST
GraphQL
/contracts/123123 /contracts/123123/afterSales /contracts/123123/documents /contracts/123123/history
single query
Fetching complex objects
Fetching complex objects
REST
GraphQL
Typization
Weak
- Enum? Int or string?
- I thought there was an array, but there was NULL!!
Strong
Array means Array
Enum means enum
REST
GraphQL
{
"insuranceStart": "2016-01-15T00:00:00.0000000+01:00",
"contractReferenceNumber": null,
"calculatedTariff": {
"pricingDetails": {
"paymentPeriod": 4,
"amount": 12.28982,
"isInvoiceAllowed": null,
"isCreditCheckRequired": null,
"isSepaMandateAcceptanceRequired": null
},
"insurance": {
"id": 273,
"efeedbackProviderId": 215,
"whiteLabelId": null,
"name": "DMB Rechtsschutz",
"description": "Securo",
"logo": "/Resources/Images/Insurance/dmb.gif"
},
"tariffInfo": {
"id": 997,
"name": "Securo",
"detailedFeatures": [
{
"id": 4,
"groupId": 12,
"groupName": "Allgemeine Leistungen",
769 more lines of JSON
/api/contracts/1890373
{ contract (id: 1890373) { calculatedTariff { pricingDetails { paymentPeriod, amount } }, insuredPerson { firstName, lastName, email } } }
{ "calculatedTariff": { "pricingDetails": { "paymentPeriod": 4, "amount": 12.28982, }, }, "insuredPerson": { "firstName": "Max", "lastName": "Pecu", "email": "andreas.freier@check24.de", } }
Overfetching
REST
GraphQL
The focus?
Long-lived network-based applications that span multiple organizations
Dynamically evolving client-server applications. The api is consumed internally.
(that's exactly what we do!)
Lots of stuff...
Libraries: Javascript, Go, .NET, Java, Python etc...
More features: Interfaces, unions, enums, fragments, named queries, mutations
https://github.com/chentsulin/awesome-graphql#lib-go
Demo
REST
GraphQL
GraphQL
- The ability to define and specify precisely the data you want for your integration
- Served over HTTP via a single endpoint which expresses the full set of capabilities of the service.
- A GraphQL server operates on a single URL/endpoint, usually /graphql
- Entities in GraphQL are not identified by URLs.
- Takes a strong opinion on avoiding versioning by providing the tools for the continuous evolution of a GraphQL schema.
- New capabilities can be added via new types and new fields on those types without creating a breaking change.
- GraphQL natively supports performing an introspection query
- GraphiQL for testing API GraphQL.
https://www.quora.com/What-is-an-API-4
https://dev-blog.apollodata.com/why-graphql-is-the-future-3bec28193807#.e2vmkolzi
https://developer.github.com/early-access/graphql/explorer/
https://www.quora.com/What-is-GraphQL
https://medium.com/chute-engineering/graphql-in-the-age-of-rest-apis-b10f2bf09bba#.uwhb1b3n4
https://medium.com/@frikille/moving-from-rest-to-graphql-e3650b6f5247#.9ht63gm1j
https://medium.freecodecamp.com/introduction-to-graphql-1d8011b80159#.xny34caxl
https://code.facebook.com/posts/1691455094417024/graphql-a-data-query-language/
https://0x2a.sh/from-rest-to-graphql-b4e95e94c26b#.fa5t5dhov
https://developer.github.com/early-access/graphql/
Resources
Thanks
John Machahuay Giraldo
GraphQL vs REST
By johnprog
GraphQL vs REST
- 1,523