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
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))
}
▶️ Run it
go run rest.go
📡 Call API
curl http://localhost:8080/users/1
📦 Response
{
"id": 1,
"name": "John",
"email": "john@example.com"
}
🧠 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
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(¶ms)
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))
}
▶️ Run it
go run graphql.go
📡 Call API
curl -X POST http://localhost:8080/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ user { name email } }"}'
📦 Response
{
"data": {
"user": {
"name": "John",
"email": "john@example.com"
}
}
}
REST vs GraphQL — Visual Understanding
REST Flow
Client
|
|---- GET /users/1 ----------> Server
|---- GET /users/1/orders ---> Server
|---- GET /orders/101/items -> Server
Multiple requests ❌
GraphQL Flow
Client
|
|---- POST /graphql ---------> Server
query {
user {
orders {
items
}
}
}
Single request ✅
⚠️ The Real Problem GraphQL Solves
REST Problem → Over-fetching
GET /users/1
Returns:
name, email, address, phone...
Even if you need only name.
REST Problem → Under-fetching
You need multiple calls to build UI.
GraphQL Solution
query {
user {
name
}
}
👉 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 → ...
💥 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
👉 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)