Skip to main content

Getting started with Go and React - API Routes

Shenzhen, China

Creating an REST API backend in Go and connecting it to a React.js frontend.

I want to prototype a Go backend for a Weather Cam tool. The backend should hold all the information related to all cameras and serve them on different routes. The backend then needs to be connected to a React.js frontend that displays the JSON data that is being served as well as to allow to add / delete cameras.

Setting up API Routes

Adding Models

Creating type declarations for our API routes:

./models/models.go

package models

import "time"

type Camera struct {
	ID					int			`json:"id"`
	Name            	string		`json:"name"`
	Username        	string		`json:"usr"`
	Password        	string		`json:"pass"`
	Address         	string		`json:"ip"`
	Created				time.Time	`json:"installed"`
	Updated				time.Time	`json:"inspected"`
	Rating				int			`json:"rating"`
	// As soon as we connect our database we will use
	// a JOIN query to get the location information.
	// Change the line to `Location []Location `json:"location"``
	// to display them.
	Location			[]Location	`json:"-"`
}

type CameraModel struct {
	ID					int			`json:"id"`
	Model				string		`json:"model"`
	Lense				string		`json:"lense"`
	Resolution			string		`json:"res"`
	Created				time.Time	`json:"install"`
	Updated				time.Time	`json:"inspect"`
}

type Location struct {
	ID              	int       	`json:"id"`
	LocationName		string		`json:"location"`
	CameraID           	string     	`json:"cid"`
	LocationID         	string    	`json:"lid"`
	Model				string		`json:"model"`
	Lense				string		`json:"lense"`
	Resolution			string		`json:"res"`
	Created 			time.Time	`json:"install"`
	Updated				time.Time	`json:"inspect"`
}

Create the API routes for all cameras and one specific camera:

package main

import (
	"net/http"

	"github.com/julienschmidt/httprouter"
)

func (app *application) routes() *httprouter.Router {
	router := httprouter.New()

	router.HandlerFunc(http.MethodGet, "/status", app.statusHandler)

	router.HandlerFunc(http.MethodGet, "/v1/camera/:id", app.getOneCamera)
	router.HandlerFunc(http.MethodGet, "/v1/cameras", app.getAllCameras)

	return router
}

Handle API JSON Response

We need to be able to send data in form of JSON to the accessing browser. We can add a utility function that abstracts that part away from our route handler:

./src/api/utilities.go

package main

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

// Create a function that takes an input, converts it to JSON
// and sends it to the browser
func (app *application) writeJSON(w http.ResponseWriter, status int, data interface{}, wrap string) error {
	// Create a wrapper that describes the data
	wrapper := make(map[string]interface{})
	// Wrap data
	wrapper[wrap] = data
	// Transform to JSON
	js, err := json.Marshal(wrapper)
	if err != nil {
		return err
	}
	// Add headers and send
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	w.Write(js)

	return nil
}

API for One Camera

./src/api/cameraHandler.go

package main

import (
	"backend/models"
	"errors"
	"net/http"
	"strconv"
	"time"

	"github.com/julienschmidt/httprouter"
)

func (app *application) getOneCamera(w http.ResponseWriter, r *http.Request) {
	// Get camera id from from the URL param
	params := httprouter.ParamsFromContext(r.Context())
	// Convert id from string to integer
	id, err := strconv.Atoi(params.ByName("id"))
	if err != nil {
		app.logger.Print(errors.New("invalid id parameter"))
	}
	// Log id to see if it is working
	app.logger.Println("camera id is", id)
	// Hardcode a camera to get started
	camera := models.Camera {
		ID: id,
		Name: "Mountain View",
		Username: "admin",
		Password: "instar",
		Address: "192.168.2.19",
		Rating: 5,
		Location: "Hongkong",
		InstallationDate: time.Date(2021, 9, 22, 0, 0, 0, 0, time.Local),
		InspectionDate: time.Now(),
	}

	err = app.writeJSON(w, http.StatusOK, camera, "camera")
	if err != nil {
		app.logger.Println(err)
	}
}

func (app *application) getAllCameras(w http.ResponseWriter, r *http.Request) {
	// TODO
}

Start the application with:

go run ./src/api/

And test the url http://localhost:4000/v1/camera/123 in your browser:

Golang React API