Tag: React

  • I Suck at REACT

    I’m working on a project with a Golang backend and a REACT frontend. Built the backend using Gin and was able to create a basic API. I wanted to not only test out the api but also figure out additional API calls I would need for the frontend. I’m primarily backend engineer and who can write frontend code when I had to. I didn’t feel like creating an entire REACT app and going through the process of figuring out the deployment so I decided to be lazy and serve html via Gin.

    Using HTML Templates in Go

    Writing HTML template in Go is not that difficult. Its basically a static html file with an action pipeline. A few examples of action pipelines:

    {{/* a comment */}}	
    {{.}}	
    {{.Title}}	
    {{if .Done}} {{else}} {{end}}	
    {{range .Todos}} {{.}} {{end}}	
    {{block "content" .}} {{end}}	
    Defines a comment
    Renders the root element
    Renders the “Title”-field in a nested element
    Defines an if-Statement
    Loops over all “Todos” and renders each using {{.}}
    Defines a block with the name “content”

    Here is an example template :

    <html>
        <header>
            <title>My Template</title>
        </header>
        <body>            
                {{range .Players}}
                    <div id="playerList">
                        {{.Rank}} - {{.Name}}
                    </div>
                {{end}
        </body>
    </html>
    

    Serving the Pages Via Gin

    Now that I have a template how do I serve it via Gin. First create a directory named templates and save the above example as index.tmpl .Data for the template must be passed using a Go struct. The files must be loaded using LoadHTMLGlob() or LoadHTMLFiles().

    Here is an example of how to serve html file using Gin:

    func main() {
    	router := gin.Default()
    	router.LoadHTMLGlob("templates/*")
            data := []struct {
    		Rank string
    		Name string
    	}{
    		{"1", "Michael Jordan"},
    		{"2", "Larry Bird"},
    	}
    	router.GET("/index", func(c *gin.Context) {
    		c.HTML(http.StatusOK, "index.tmpl", gin.H{
    			"Players": data,
    		})
    	})
    	router.Run(":8080")
    }
    
    

    This code will read templates from the templates directory, create an array with the required data and display the template using the provided data. Gin will detect if a change has been made to templates and automatically reload it. Templates can use CSS and Javascript if you can to get more fancy.

    This is a simple workaround to avoid having to create a full blown REACT app and shouldn’t be seen as a long term solution.

  • Working on a New Project

    I’m working on a new project. Can’t really disclose a lot but I can tell you its going to be based on Golang/REACT and I’m hoping to scale it to handle at least 100k hits per day. Because I’m a cheap bastard, I’m going to try to spend as little money as possible. I plan to document the entire process here.

    Technologies Used

    • Golang
    • Docker
    • SQLite
    • React

    3rd Party Services Used

    • Oracle Cloud Infrastructure/Google Cloud
      • Hosting the Golang backend
    • OCI NoSQL database/Firebase
      • Hosting user generated data
    • SupaBase
      • User authenitcation
    • PostHog
      • Analytics
    • Vercel
      • Hosting the React Frontend

    Why SQLITE?

    The project that I’m working on relies on a lot of static data. By storing this data in an SQLite, I’m decreasing the need to make additional network calls to a remote database. The initial data would consist of about 50,000 rows in the SQLite database which would take up about 5-6 megabytes. Each database would be deployed in a docker container with the Golang application.

    SQLite can easily handle 100k http requests per day (You can read more about uses for SQLite here). I’m enabling WAL mode (Write-Ahead Logging) to make the database more performant since the database would only be accessed via a single host.

    Feel free to comment or reach out to me on Bluesky (https://bsky.app/profile/rooseveltanderson.bsky.social)