DEV Community

Cover image for Deploy a Golang serverless function for a demo form with htmx
YPChen
YPChen

Posted on

Deploy a Golang serverless function for a demo form with htmx

The boilplate I begin with is the production of the tutorial by BugBytes on Youtube in the video: Golang + HTMX - Creating a Go webserver / HTMX Integration / Template Fragments. It’s really good and straightforward.

And I made these changes and will talk about them in this article:

  • Instead of Booststrap, I used Tailwind CSS as the CSS library.
  • I deployed the project on Zeabur, which is a personal preference (mainly because it’s free for the demo 😅). However, feel free to choose any similar service that suits your needs.
  • I use go-chi for handling routes and to server static file(stylesheet).
  • I utilized the Go embed directive for the serverless plan on Zeabur.
  • Additionally, I explored htmx a bit more for reset inputs and animation."

The demo page: https://yp-go-htmx-simpleform.zeabur.app/

The repo: https://github.com/AlliesChen/go-htmx-simpleform/tree/main

DISCLAIMER: I’m not a GoLang expert, and I’m not yet a backend developer. However, I have experience in front-end development. Any suggestions to improve the structure of the demo or to correct any misunderstandings in this article would be greatly appreciated. 🙏

Go:embed for using files in serverless functions

To learn more about serverless functions, you can watch this video.

Serverless function cannot access the local file system of the server. Therefore, packing static files such as templates and stylesheets is necessary to serve them as part of the response.

As Zeabur is a platform that offers free hosting for serverless functions, the remaining challange will be how to include external files, such as templates or stylesheets, in the code package.

With go:embed, a feature that enables embedding files into Go binaries, things couldn't be more easier.

Here is my file structure:

/static
 |— output.css
/templates
 |— index.html
main.go
Enter fullscreen mode Exit fullscreen mode

Add the comments:
(PLEASE MAKE SURE NO SPACE BETWEEN THE TWO SLASH AND go:embed or it won't work)

var (
    //go:embed templates
    templates embed.FS
    //go:embed static
    static embed.FS
    pages  = map[string]string{
        "/":          "templates/index.html",
        "/add-film/": "templates/index.html",
    }
)
Enter fullscreen mode Exit fullscreen mode

In the handlers, rather than using template.ParseFiles, we focus on the folders using template.ParseFS with the page which is the path to the file includes the folder name.

// GET /
getPage := func(w http.ResponseWriter, r *http.Request) {
    page, ok := pages[r.RequestURI]
    // ...
    tmpl, err := template.ParseFS(templates, page)
    // ...
    if err := tmpl.Execute(w, films); err != nil {
        // ...
        return
    }
}
// POST /add-film
addFilm := func(w http.ResponseWriter, r *http.Request) {
    page, ok := pages[r.RequestURI]
    // ...
    tmpl, err := template.ParseFS(templates, page)
    // ...
    if err := tmpl.ExecuteTemplate(w, "film-list-element", Film{
        Title:    title,
        Director: director,
    }); err != nil {
        // ...
        return
    }
}
Enter fullscreen mode Exit fullscreen mode

That's it. Execute go run main.go and visit http://localhost:8000/ with your browser. There should be nothing different from BugBytes' production.

Include stylesheet built by Tailwind CSS

Similar to what we did for the HTML file in the templates directory, the serverless plan also requires embedding the stylesheet within the static folder, as previously accomplished.

In contrast to the earlier step, there is no need to parse the stylesheet. Instead, serve it directly when the website requests the /static path:

fileServer := http.FileServer(http.FS(static))
router.Handle("/static/*", fileServer)
Enter fullscreen mode Exit fullscreen mode

This ensures that the stylesheet is readily available for use by the website without additional processing." 😊

Top comments (0)