Here are some examples about GraphQL and REST API to show the differences between GraphQL and REST API.
GraphQL
Golang code Implementation as follows:
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"github.com/graphql-go/graphql"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
var userType = graphql.NewObject(
graphql.ObjectConfig{
Name: "User",
Fields: graphql.Fields{
"id": &graphql.Field{
Type: graphql.Int,
},
"name": &graphql.Field{
Type: graphql.String,
},
},
},
)
var queryType = graphql.NewObject(
graphql.ObjectConfig{
Name: "Query",
Fields: graphql.Fields{
"user": &graphql.Field{
Type: userType,
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{
Type: graphql.Int,
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
id, ok := p.Args["id"].(int)
if ok {
if id == 1 {
return User{ID: 1, Name: "Alice"}, nil
} else if id == 2 {
return User{ID: 2, Name: "Bob"}, nil
}
}
return nil, nil
},
},
},
},
)
var schema, _ = graphql.NewSchema(
graphql.SchemaConfig{
Query: queryType,
},
)
func executeQuery(query string, schema graphql.Schema) *graphql.Result {
result := graphql.Do(graphql.Params{
Schema: schema,
RequestString: query,
})
if len(result.Errors) > 0 {
fmt.Printf("Unexpected errors inside ExecuteQuery: %v", result.Errors)
}
return result
}
func main() {
http.HandleFunc("/graphql", func(w http.ResponseWriter, r *http.Request) {
result := executeQuery(r.URL.Query().Get("query"), schema)
json.NewEncoder(w).Encode(result)
})
fmt.Println("Now server is running on port 8088")
fmt.Println("Test with Get : curl -g 'http://localhost:8088/graphql?query={user(id:1){name}}'")
fmt.Println("Test with Post method: curl -XPOST -H 'Content-Type: application/json' -d '{\"query\": \"{user(id:2){id name}}\"}' http://localhost:8088/graphql ")
log.Fatal(http.ListenAndServe(":8088", nil))
}
Then call the server by curl
:
curl -g 'http://localhost:8088/graphql?query={user(id:1){name}}'
You can see it:
D08042 :: ~ % curl -g 'http://localhost:8088/graphql?query={user(id:1){name}}'
{"data":{"user":{"name":"Alice"}}}
Another Command as follows:
CheverJohn :: ~ % curl -s -g 'http://localhost:8088/graphql?query={user(id:1){name}}' | jq '.'
{
"data": {
"user": {
"name": "Alice"
}
}
}
CheverJohn :: ~ % curl -s --show-error -g 'http://localhost:8088/graphql?query={user(id:1){name}}' | jq '.'
{
"data": {
"user": {
"name": "Alice"
}
}
}
REST API
Golang Codes as follows:
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
var users = []User{
{ID: 1, Name: "Alice"},
{ID: 2, Name: "Bob"},
}
func getUser(id int) (*User, error) {
for _, user := range users {
if user.ID == id {
return &user, nil
}
}
return nil, fmt.Errorf("user with ID %d not found", id)
}
func userHandler(w http.ResponseWriter, r *http.Request) {
idStr := r.URL.Path[len("/users/"):]
id, err := strconv.Atoi(idStr)
if err != nil {
http.Error(w, "Invalid user ID", http.StatusBadRequest)
return
}
user, err := getUser(id)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(user)
}
func main() {
http.HandleFunc("/users/", userHandler) // Handles requests like /users/1, /users/2, etc.
fmt.Println("Now server is running on port 8088")
fmt.Println("Test with Get: curl http://localhost:8088/users/1")
log.Fatal(http.ListenAndServe(":8088", nil))
}
And the result as follows:
CheverJohn :: ~ % curl -s -g http://localhost:8088/users/1 | jq '.'
{
"id": 1,
"name": "Alice"
}