What is GraphQL?

profile image

Learn about GraphQL, a data query language created to overcome the limitations of REST APIs, and its pros and cons compared to REST APIs.

This post has been translated by DeepL . Please let us know if there are any mistranslations!

GraphQL is a data query language developed by Facebook and designed to make APIs faster, more flexible, and more developer-friendly.

Unlike REST APIs, it allows clients to define the data structures they need and get the information they want with a single request. you can also use a type system to clearly define the data structure of requests and responses and make your code more reliable.

"The best feature is that** you can get only what you want, exactly what you need**.

REST API 🆚 GraphQL

imagine you have a REST API that contains the following information about countries. you call the /countries endpoint to get a list of countries.

/countries

json
// GET /countries 응답
[
  {
    "code": "AD",
    "name": "Andorra",
    "capital": "Andorra la Vella",
    "region": "Europe"
  },
  {
    "code": "AE",
    "name": "United Arab Emirates",
    "capital": "Abu Dhabi",
    "region": "Asia"
  },
  {
    "code": "AF",
    "name": "Afghanistan",
    "capital": "Kabul",
    "region": "Asia"
  },
  // ... 200개 이상의 국가 데이터
]

we got the code, which is the unique ID of a specific country. now, if we want to find out more information about that country, we need to call the API for it again.

/countires/KR

javascript
// GET /countries/KR 응답
{
  "code": "KR",
  "name": "South Korea",
  "native": "대한민국",
  "phone": "82",
  "capital": "Seoul",
  "currency": "KRW",
  "languages": ["ko"],
  "emoji": "🇰🇷",
  "region": "Asia",
  "subregion": "Eastern Asia",
  "states": [
    { "name": "Seoul", "code": "11" },
    { "name": "Busan", "code": "26" },
    { "name": "Incheon", "code": "28" },
    // ... 더 많은 지역
  ]
}

what's wrong with this approach?

  • Over fetching problem: If we just need the ability to show the country name and capital, we don't need to fetch any other information. but when we call the API, we need to get all the data from all the countries. as the amount of data grows, the amount of traffic increases, which can lead to performance degradation.
  • Under fetching problem: It takes two API calls to show country details. therefore, showing countries and their details together requires multiple API calls.

Workaround with GraphQL

you can solve the REST API issues listed above with GraphQL as follows.

  • all requests can be handled through a single endpoint. this simplifies management and maintenance.
  • clients can request only the data they need. clients can specify the structure of the data they need, reducing unnecessary data transfer and increasing network efficiency.

/countries

graphql
query {
  countries {
    name
    capital
    emoji
  }
}

Response

json
{
  "data": {
    "countries": [
      {
        "name": "Andorra",
        "capital": "Andorra la Vella",
        "emoji": "🇦🇩"
      },
      {
        "name": "United Arab Emirates",
        "capital": "Abu Dhabi",
        "emoji": "🇦🇪"
      },
      {
        "name": "Afghanistan",
        "capital": "Kabul",
        "emoji": "🇦🇫"
      },
      // ... 더 많은 국가들
    ]
  }
}

/countries/KR

json
query {
  country(code: "KR") {
    name
    native
    capital
    emoji
    currency
    languages {
      name
      native
    }
    continent {
      name
    }
  }
}

Response

json
{
  "data": {
    "country": {
      "name": "South Korea",
      "native": "대한민국",
      "capital": "Seoul",
      "emoji": "🇰🇷",
      "currency": "KRW",
      "languages": [
        {
          "name": "Korean",
          "native": "한국어"
        }
      ],
      "continent": {
        "name": "Asia"
      },
    }
  }
}

i got all the information I needed with just one request! 🫢 🫢

Benefits of GraphQL

1. single endpoint

One of the features of GraphQL is that it uses only one endpoint. While REST APIs require different endpoints for different resources ( /countries, /countries/KR, /countries/KR/borders, /languages, etc.), GraphQL typically only uses a single URL: /graphql.

  • simplifies front-end development: Developers only need to know one endpoint, rather than having to remember multiple endpoints or browse documentation.
  • increased security: Authentication and authorization logic can be centralized because only one entry point needs to be secured.

2. request exactly the data you need (eliminate overfetching)

GraphQL allows clients to request exactly the data they need. this can solve the problem of overfetching.

  • reducednetwork traffic: Reduced bandwidth usage by not sending unnecessary data.
  • improved response time: Server response time can be improved because only the necessary data is processed.

3. fetch related data in a single request (solves under fetching)

GraphQL allows you to fetch data from multiple resources in a single request. this can solve the problem of underfetching.

  • reduced network requests: Fetch all data in one request instead of multiple API calls.
  • eliminatewaterfall requests: Avoid making sequential API calls that are common in REST.
  • simplifies front-end code: No need for complex code to coordinate multiple API calls.

4. strong type system

GraphQL is based on a strict type system. the type of each field is clearly defined, which greatly improves the reliability and predictability of the API.

  • compile-time error detection: Type errors can be caught during development.
  • automatic code generation: client code can be automatically generated based on type definitions. (TypeScript interfaces, etc.).
  • Improved IDE support: improved development environment support, including code autocompletion, type checking, and more.
  • clear contracts: Clear data contracts between front-end and back-end.

Cons of GraphQL

1. burdensome to handle complex queries

GraphQL provides query flexibility to the client, but this can create a burden on the server side.

  • performance impact of complex queries: Highly nested queries or complex queries that request multiple resources can put a heavy load on the server.
typescript
query NestedQuery {
  continents {
    countries {
      languages {
        countries {
          languages {
            countries {
              ...
            }
          }
        }
      }
    }
  }
}
  • possible resource attack: A malicious user can intentionally send very complex queries that consume server resources.

2. complexity of caching implementation

While REST APIs can be cached simply based on URLs, GraphQL requires a more complex caching strategy.

3. differences in error handling

  • Lack of utilization of HTTP status codes: Errors are embedded in the response body, which can be tricky to handle.
  • handling partialfailures: Only part of a query can fail, so the client has to deal with partial success/failure scenarios.
  • debuggingerrors: It can be more difficult to debug when something goes wrong with a complex query.

4. the danger of too much flexibility

GraphQL's flexibility can be a double-edged sword.

  • API versioning confusion: The ease of adding fields can lead to a lack of explicit versioning.
  • increasedquery complexity: Client queries can become increasingly complex over time.
  • exposingbackend logic: Flexible queries can unintentionally expose internal system structure.
  • Difficult tounderstand API usage patterns: Different client query patterns can make it difficult to identify the most important data and fields.

GraphQL primitives

One of the powerful features of GraphQL is its type system. let's take a look at what types are available.

TypeDescription
StringUTF-8 string
IDDefaults to a String, but indicates that it acts as a unique identifier
IntA signed 32-bit integer
FloatA signed floating point value
BooleanTrue/False

!(Non Null)

indicates that certain fields are not allowed to contain null.

examples

graphql
const typeDefs = gql`
	type Supplies {
	    id: ID!
	    name: String!
	    price: Int
	}
`

enum (enum type)

a type that returns one of a set of predefined values.

graphql
const typeDefs = gql`
  enum Role {
      developer
      designer
      planner
  }
  enum NewOrUsed {
      new
      used
  }
`

[] (array type)

indicates that the specific type is an array.

graphql
const typeDefs = gql`
	type Foods {
		ingredients: String[]
	}
`

it can also have different meanings depending on the location of !.

선언부users: nullusers: [ ]users: [..., null]
[String]
[String!]
[String]!
[String!]!

union types

use this when you want to combine multiple types that have been created.

graphql
const typeDefs = gql`
  union Given = Equipment | Supply
`;

interface type

this type is for creating similar object types, and is written for implements. if an inherited object does not implement the fields of an interface, an error is raised.

typescript
interface Produce {
  id: ID!
  name: String!
  quantity: Int!
  price: Int!
}

# OK
type Fruit implements Produce {
  id: ID!
  name: String!
  quantity: Int!
  price: Int!
}

# ERROR !!
type Vegetable implements Produce {
  id: ID!
  name: String!
  quantity: Int!
}

input type

you can specify the type of parameters that should go into a query or mutation.

graphql
input PostPersonInput {
    first_name: String!
    last_name: String!
}

type Mutation {
    postPerson(input: PostPersonInput): People!
}

when should you choose GraphQL?

GraphQL is a powerful tool for creating more flexible and efficient APIs. While REST APIs are still a good choice in many situations, GraphQL can offer clear advantages when you have complex data requirements and need to support a wide variety of clients.

however, it's important to remember that GraphQL is a contextual tool, not a one-size-fits-all solution. it's important to analyze the requirements of your project and choose between REST APIs and GraphQL.

graphQL can be a good choice in the following situations

  1. applications with complex data relationships

    • complex relationships between multiple entities, such as country information apps
    • social networks with multiple relationships between users, posts, comments, likes, etc
  2. need to support a variety of clients

    • different data requirements on different platforms, including web, mobile apps, and desktop
    • each client needs to pull customized data from the same backend
  3. rapid product iterations and front-end development speed are important to you

    • need to easily accommodate front-end requirements without back-end changes
    • startups or agile environments where user interfaces and features change frequently
  4. need to integrate microservices

    • when you need to consolidate data from multiple microservices into one consistent API
    • You are implementing the Backend For Frontend (BFF) pattern

When REST still makes sense

in the following situations, a REST API might be a better fit.

  1. if you're primarily doing simple CRUD operations

    • applications with few relationships and simple data structures
    • when data request patterns are consistent and predictable
  2. When HTTP caching is important

    • when efficient HTTP caching is critical, such as for public APIs
    • When caching through a CDN is a critical performance factor
  3. when file uploading is a key feature

    • if large file handling and streaming are your primary requirements
  4. you need to minimize the learning curve for your team

    • your team is familiar with REST and has limited time to learn a new paradigm

wrapping up

as with any technology, GraphQL comes with certain tradeoffs. At the end of the day, the most important thing is to meet the needs of your users and your business. Whether you choose GraphQL, REST, or a combined approach, make sure you choose the right technology for your project's specific situation and goals!

references https://www.yalco.kr/@graphql-apollo/3-2/

❤️ 0
🔥 0
😎 0
⭐️ 0
🆒 0