82 Connecting a React App to a graphql-go Backend
82 Connecting a React App to a graphql-go Backend
A Practical GraphQL API Implementation for the Modern Frontend Era
In the era of modern web applications, communication between the frontend and backend has become one of the critical aspects that determines the success of a technology integration. React, as one of the most popular frontend frameworks, is often paired with a variety of backends, including both REST and GraphQL. In this article, I’ll walk through, in practical terms, how to connect a React App to a GraphQL backend built with graphql-go , the GraphQL library for the Go language.
Why GraphQL?
Before we dive into the implementation, let’s briefly review: why GraphQL? If you’re already comfortable with REST APIs, GraphQL offers several important advantages:
Single Endpoint
No need to create many endpoints; a single endpoint is enough for all of your query/mutation needs.Flexible Query
The client decides exactly which data to fetch, without being constrained by the shape of the API response.Efficient
Reduces over-fetching and under-fetching of data.
By combining React and GraphQL, frontend developers can be more productive while also minimizing the data load over the network.
A Simple Architecture
Before we start coding, let’s visualize our simple architecture. Here is a diagram of the communication flow between the React App and the graphql-go backend:
graph TD
A[User] --> B[React App]
B -- Query/Mutation --> C[GraphQL Endpoint (Go Server)]
C -- data response --> B
1. Building a GraphQL Backend with Go
Installation
Set up a Go project and install the required packages:
1go get github.com/graphql-go/graphql
2go get github.com/graphql-go/handlerA Simple GraphQL Schema
Imagine we’re building a simple Todo List application. Here is what its GraphQL data type and resolver look like.
1package main
2
3import (
4 "encoding/json"
5 "net/http"
6 "github.com/graphql-go/graphql"
7 "github.com/graphql-go/handler"
8)
9
10// Dummy data store
11var todos = []map[string]interface{}{
12 {"id": "1", "content": "Belajar GraphQL", "completed": false},
13}
14
15func main() {
16 // Define Todo Type
17 todoType := graphql.NewObject(graphql.ObjectConfig{
18 Name: "Todo",
19 Fields: graphql.Fields{
20 "id": &graphql.Field{Type: graphql.String},
21 "content": &graphql.Field{Type: graphql.String},
22 "completed": &graphql.Field{Type: graphql.Boolean},
23 },
24 })
25
26 // Query: Fetch all Todos
27 fields := graphql.Fields{
28 "todos": &graphql.Field{
29 Type: graphql.NewList(todoType),
30 Resolve: func(p graphql.ResolveParams) (interface{}, error) {
31 return todos, nil
32 },
33 },
34 }
35
36 rootQuery := graphql.ObjectConfig{Name: "RootQuery", Fields: fields}
37 schemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}
38 schema, err := graphql.NewSchema(schemaConfig)
39 if err != nil {
40 panic(err)
41 }
42
43 // Create the GraphQL handler
44 h := handler.New(&handler.Config{
45 Schema: &schema,
46 Pretty: true,
47 GraphiQL: true,
48 })
49
50 http.Handle("/graphql", h)
51 http.ListenAndServe(":8080", nil)
52}Explanation:
- Todo Type: Defines the structure of the Todo data.
- Query “todos”: Returns the list of todos.
- Uses handler
for the
/graphqlendpoint, so you can try it directly via GraphiQL.
2. Building a React App Connected to the GraphQL Backend
We’ll use Apollo Client as the GraphQL client for React, because it’s stable, well known, and has comprehensive documentation.
Installing Apollo Client
1npm install @apollo/client graphqlCreating the Query Client
1// src/apollo.js
2import { ApolloClient, InMemoryCache } from '@apollo/client';
3
4export const client = new ApolloClient({
5 uri: 'http://localhost:8080/graphql',
6 cache: new InMemoryCache(),
7});Creating the Fetch Todo Component
1import React from 'react';
2import { ApolloProvider, useQuery, gql } from '@apollo/client';
3import { client } from './apollo';
4
5const GET_TODOS = gql`
6 query GetTodos {
7 todos {
8 id
9 content
10 completed
11 }
12 }
13`;
14
15function TodoList() {
16 const { loading, error, data } = useQuery(GET_TODOS);
17
18 if (loading) return <p>Memuat...</p>;
19 if (error) return <p>Error: {error.message}</p>;
20
21 return (
22 <ul>
23 {data.todos.map((todo) => (
24 <li key={todo.id}>
25 {todo.content} {todo.completed ? "✔️" : ""}
26 </li>
27 ))}
28 </ul>
29 );
30}
31
32function App() {
33 return (
34 <ApolloProvider client={client}>
35 <h1>Todo List</h1>
36 <TodoList />
37 </ApolloProvider>
38 );
39}
40
41export default App;3. End-to-End Simulation
Let’s review the flow:
- The frontend (React) sends a Query to
/graphqlon the Go server (see theGET_TODOSquery above). - The backend (Go) receives the query, runs the resolver, and sends back the data.
- Apollo Client receives the data, and the React component renders the UI.
4. Comparison Table: REST vs GraphQL
| REST | GraphQL | |
|---|---|---|
| Endpoint | Many, based on resource | 1 endpoint |
| Response | Fixed shape | Can be specified at query time |
| Over/Under-fetch | Happens often | Rare, the client fetches exactly what it needs |
| Documentation | Swagger, OpenAPI (manual) | Self-documenting (via introspection & tools: GraphiQL, etc.) |
5. Troubleshooting & Tips
CORS
When the frontend and backend run on different ports, enable CORS on the Go backend.1// Add a simple middleware for CORS 2http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 3 w.Header().Set("Access-Control-Allow-Origin", "*") 4 if r.Method == "OPTIONS" { 5 w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS") 6 w.Header().Set("Access-Control-Allow-Headers", "Content-Type") 7 return 8 } 9 http.DefaultServeMux.ServeHTTP(w, r) 10})Don’t forget to start the Go server before running
npm startfor the React App.Use GraphiQL in the browser to explore and debug your queries.
6. Going Further
- Adding a Mutation:
Define a mutation on the backend and wire it up with Apollo on the frontend. - Auth:
Integrate JWT or an OAuth mechanism for authentication. - Deployment:
Use Docker/docker-compose to make dev/prod easier.
Conclusion
Connecting a React App to a graphql-go backend is relatively straightforward, and incredibly powerful for modern applications. The combination of the two is a great fit for everyone from small teams to enterprises with flexible data needs.
Going forward, GraphQL will only grow in popularity as the frontend-driven development trend continues to be adopted.
Give it a try, and I hope it proves useful for your next project!
References
Questions or discussion?
Feel free to leave a comment below! 👋