DEV Community

Cover image for GraphQL vs REST - Which One Should You Really Use?
Fazal Mansuri
Fazal Mansuri

Posted on

GraphQL vs REST - Which One Should You Really Use?

For years, REST APIs have been the standard.

Then GraphQL came in with promises like:

  • “Fetch exactly what you need”
  • “Reduce API calls”
  • “More flexible APIs”

But here’s the reality:

GraphQL is not a replacement for REST.
It’s a different trade-off.

Let’s break it down — with real code you can run.


🧠 What is REST?

REST is a resource-based API design.

You expose endpoints like:

GET /users/1
GET /users/1/orders
Enter fullscreen mode Exit fullscreen mode

Each endpoint returns fixed structure data.


⚙️ REST API — Fully Working Go Example

👉 Save as rest.go

package main

import (
    "encoding/json"
    "log"
    "net/http"
)

type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

func getUserHandler(w http.ResponseWriter, r *http.Request) {
    user := User{
        ID:    1,
        Name:  "John",
        Email: "john@example.com",
    }

    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(user)
}

func main() {
    http.HandleFunc("/users/1", getUserHandler)

    log.Println("REST server running on http://localhost:8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}
Enter fullscreen mode Exit fullscreen mode

▶️ Run it

go run rest.go
Enter fullscreen mode Exit fullscreen mode

📡 Call API

curl http://localhost:8080/users/1
Enter fullscreen mode Exit fullscreen mode

📦 Response

{
  "id": 1,
  "name": "John",
  "email": "john@example.com"
}
Enter fullscreen mode Exit fullscreen mode

🧠 What is GraphQL?

GraphQL is a query-based API system.

Instead of multiple endpoints:

  • You use a single endpoint
  • Client decides what data it needs

⚙️ GraphQL API — Fully Working Go Example

👉 Save as graphql.go

Step 1: Install dependency

go mod init graphql-example
go get github.com/graphql-go/graphql
Enter fullscreen mode Exit fullscreen mode

Step 2: Full working code

package main

import (
    "encoding/json"
    "log"
    "net/http"

    "github.com/graphql-go/graphql"
)

type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

var userData = User{
    ID:    1,
    Name:  "John",
    Email: "john@example.com",
}

func main() {

    // Define User type
    userType := graphql.NewObject(graphql.ObjectConfig{
        Name: "User",
        Fields: graphql.Fields{
            "id": &graphql.Field{
                Type: graphql.Int,
            },
            "name": &graphql.Field{
                Type: graphql.String,
            },
            "email": &graphql.Field{
                Type: graphql.String,
            },
        },
    })

    // Root query
    rootQuery := graphql.NewObject(graphql.ObjectConfig{
        Name: "Query",
        Fields: graphql.Fields{
            "user": &graphql.Field{
                Type: userType,
                Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                    return userData, nil
                },
            },
        },
    })

    schema, err := graphql.NewSchema(graphql.SchemaConfig{
        Query: rootQuery,
    })
    if err != nil {
        log.Fatal(err)
    }

    // GraphQL handler
    http.HandleFunc("/graphql", func(w http.ResponseWriter, r *http.Request) {
        var params struct {
            Query string `json:"query"`
        }

        err := json.NewDecoder(r.Body).Decode(&params)
        if err != nil {
            http.Error(w, "invalid request body", http.StatusBadRequest)
            return
        }

        result := graphql.Do(graphql.Params{
            Schema:        schema,
            RequestString: params.Query,
        })

        w.Header().Set("Content-Type", "application/json")
        json.NewEncoder(w).Encode(result)
    })

    log.Println("GraphQL server running on http://localhost:8080/graphql")
    log.Fatal(http.ListenAndServe(":8080", nil))
}
Enter fullscreen mode Exit fullscreen mode

▶️ Run it

go run graphql.go
Enter fullscreen mode Exit fullscreen mode

📡 Call API

curl -X POST http://localhost:8080/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ user { name email } }"}'
Enter fullscreen mode Exit fullscreen mode

📦 Response

{
  "data": {
    "user": {
      "name": "John",
      "email": "john@example.com"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

REST vs GraphQL — Visual Understanding

REST Flow

Client
  |
  |---- GET /users/1 ----------> Server
  |---- GET /users/1/orders ---> Server
  |---- GET /orders/101/items -> Server

Multiple requests ❌
Enter fullscreen mode Exit fullscreen mode

GraphQL Flow

Client
  |
  |---- POST /graphql ---------> Server
        query {
          user {
            orders {
              items
            }
          }
        }

Single request 
Enter fullscreen mode Exit fullscreen mode

⚠️ The Real Problem GraphQL Solves

REST Problem → Over-fetching

GET /users/1
Enter fullscreen mode Exit fullscreen mode

Returns:

name, email, address, phone...
Enter fullscreen mode Exit fullscreen mode

Even if you need only name.


REST Problem → Under-fetching

You need multiple calls to build UI.


GraphQL Solution

query {
  user {
    name
  }
}
Enter fullscreen mode Exit fullscreen mode

👉 Exact data only.


⚖️ REST vs GraphQL — Honest Comparison

🧩 REST

✅ Simple
✅ Easy caching
✅ Easy debugging
❌ Multiple calls
❌ Over-fetching


🧩 GraphQL

✅ Flexible
✅ Single request
❌ Complex
❌ Hard caching

Note: REST uses native HTTP caching (like CDNs and browser headers), while GraphQL requires complex, custom caching strategies because queries are typically sent via POST.

❌ Query abuse risk


⚠️ Common Mistakes

❌ “GraphQL is always better”

No.

❌ Using GraphQL for simple CRUD

Overkill.

❌ Ignoring query complexity

Bad query:

users → posts → comments → replies → ...
Enter fullscreen mode Exit fullscreen mode

💥 Performance issue


🧠 When to Use What

✅ Use REST when:

  • Simple APIs
  • CRUD operations
  • Strong caching needed
  • Easy debugging required

✅ Use GraphQL when:

  • Complex frontend
  • Aggregated data
  • Multiple services
  • Frequent UI changes

🔗 Real-World Architecture

Many companies use the GraphQL Gateway (or BFF) pattern:

Frontend → GraphQL Gateway → REST microservices
Enter fullscreen mode Exit fullscreen mode

👉 GraphQL acts as an aggregation layer, allowing you to combine multiple REST responses into one, without refactoring the legacy backend.


🏁 Final Thoughts

GraphQL vs REST is not a battle.

It’s a design decision.


🎯 Key Takeaways:

  • REST = simple and predictable
  • GraphQL = flexible but complex
  • Both solve real problems
  • Choose based on use-case

🚀 Final Tip

If your API:

👉 Is simple → use REST
👉 Needs flexibility → use GraphQL

Top comments (0)