GraphQL
Graph Query language. Fixes the under-fetching and over-fetching problem.
NOT a database
GraphQL is not a database. Rather, it’s a query language that is data-agnostic.
Why not just use MySQL? And how to integrate it with a database?
GraphQL is designed in a way that allows you to write clean code on the server, where every field on every type has a focused single-purpose function for resolving that value.
Resources
Tip
Every GraphQL service defines a set of types which completely describe the set of possible data you can query on that service. Then, when queries come in, they are validated and executed against that schema.
In GraphQL (and specifically Absinthe in Elixir), the schema is a blueprint or contract that defines:
- The data types (like
Post
,User
, etc.). - The queries (like
posts
,users
) that clients can perform to retrieve data. - Mutations (like
createPost
,updateUser
) for changing data. - The relationships between types (e.g., how a
Post
relates to aUser
). - The arguments that queries or mutations can accept (e.g., filtering or pagination arguments).
GraphQL comes with a set of default scalar types out of the box: (source)
Int
: A signed 32‐bit integerFloat
: A signed double-precision floating-point valueString
: A UTF‐8 character sequenceBoolean
:true
orfalse
ID
: The ID scalar type represents a unique identifier, often used to refetch an object or as the key for a cache. The ID type is serialized in the same way as aString
; however, defining it as anID
signifies that it is not intended to be human‐readable.
Query
{
human(id: "1000") {
name
height(unit: FOOT)
}
}
Object Types
The most basic components of a GraphQL schema are object types, which just represent a kind of object you can fetch from your service, and what fields it has.
type Character {
name: String!
appearsIn: [Episode!]!
}
String!
means that the field is non-nullable
Every field on a GraphQL object can have zero or more arguments.
type Starship {
id: ID!
name: String!
length(unit: LengthUnit = METER): Float
}
- how are these arguments passed and used?
- and there are aliases if I remember correctly
Schemas and mutation types
Most types in your schema will just be normal object types, but there are two special schemas:
query
mutation
These are special because they define the entry point of every GraphQL query.
schema {
query: Query
mutation: Mutation
}
query {
hero {
name
}
droid(id: "2000") {
name
}
}
We need to define the Query
rtpe.
type Query {
hero(episode: Episode): Character
droid(id: ID!): Droid
}
Interfaces
An Interface is an abstract type that includes a certain set of fields that a type must include to implement the interface.
For example, you could have an interface Character that represents any character in the Star Wars trilogy:
- ooohh it’s like TypeScript
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
}
But why...
Interfaces are useful when you want to return an object or set of objects, but those might be of several different types.
Reusability: When multiple types share common fields (like Character in your Star Wars example), you don’t want to repeat those fields across different type definitions.
Input Types
input types look exactly the same as regular object types, but with the keyword input
instead of type
:
Inputs are used for passing data into mutations. Unlike object types, input types are designed specifically for input purposes (e.g., creating, updating, or deleting data). They define what shape of data is expected when clients want to modify the data on the server.
Full use case
input ReviewInput {
stars: Int!
commentary: String
}
Defining the Mutation:
type Mutation {
submitReview(input: ReviewInput!): Review
}
Executing the Mutation (from the client):
mutation {
submitReview(input: { stars: 5, commentary: "Great product!" }) {
stars
commentary
}
}
Execution
Resolvers
https://www.reddit.com/r/graphql/comments/rffr95/i_dont_understand_how_graphql_can_be_performant/
Misc
Why GraphQL?
Well REST doesn’t scale really well. You need to set up different endpoints. Else it will just send you a huge chunk of data. Hmm is this true? Yes if you do a GET request. But like with a POST request, you can receive data afterwards based on the fields you request.
- I guess the argument is POST was not designed for that principle.
- Actually, GET requests can also include query parameters to specify fields, reducing overfetching by requesting only necessary data.
But it seems GraphQL is more configurable.
GraphQL services typically respond using JSON, however the GraphQL spec does not require it.