Goa provides a straightforward way to serve static assets such as HTML, CSS,
JavaScript, and images through the Files
function in the service DSL. This
function allows you to map HTTP paths to directories or specific files on disk,
enabling your service to deliver static content efficiently.
Files
FunctionThe Files
function defines an endpoint that serves static assets via HTTP. It
behaves similarly to the standard http.ServeFile
function, handling requests
to serve files or directories based on the defined path.
Files(path, filename string, dsl ...func())
{*filepath}
) to match variable segments of the URL.To serve a single file, define the Files
function with a specific path and the file’s location on disk.
var _ = Service("web", func() {
Files("/index.html", "/www/data/index.html", func() {
// All optional, but useful for OpenAPI spec
Description("Serve home page.")
Docs(func() {
Description("Additional documentation")
URL("https://goa.design")
})
})
})
In this example:
/index.html
- Requests to /index.html
will serve the file located at /www/data/index.html
./www/data/index.html
- Absolute path to the file on disk.To serve multiple files from a directory, use a wildcard in the path.
var _ = Service("web", func() {
Files("/static/{*path}", "/www/data/static", func() {
Description("Serve static assets like CSS, JS, and images.")
})
})
In this example:
/static/{*path}
- The {*path}
wildcard matches any subpath after /static/
, allowing dynamic file serving./www/data/static
- Directory containing static assets.When using a wildcard path like /static/{*path}
, Goa combines the wildcard value with the base directory to locate the file:
Filename
For example, with the configuration:
Files("/static/{*path}", "/www/data/static")
If the URL path is /static/css/style.css
, Goa will resolve to /www/data/static/css/style.css
.
When serving directories, ensure that index files (e.g., index.html
) are
correctly mapped. If you do not explicitly map index.html
under a wildcard
path, the underlying http.ServeFile
call will return a redirect to ./
instead of the index.html
file.
var _ = Service("bottle", func() {
Files("/static/{*path}", "/www/data/static", func() {
Description("Serve static assets for the SPA.")
})
Files("/index.html", "/www/data/index.html", func() {
Description("Serve the SPA's index.html for client-side routing.")
})
})
This configuration ensures that requests to /index.html
serve the index.html
file, while requests to /static/*
serve files from the static directory.
When implementing static file serving in your Goa service, you have several options for managing and serving the files:
Using the File System: In your service implementation, use the file system to serve embedded files.
Using Embedded Files: The embed
package in Go 1.16+ allows you to embed
static files directly into your binary, making deployment simpler and more
reliable.
This example demonstrates how to serve static files using the embed
package.
Assuming the following design:
var _ = Service("web", func() {
Files("/static/{*path}", "static")
})
The service implementation can be:
package web
import (
"embed"
// ... other imports ...
)
//go:embed static
var StaticFS embed.FS
// ... other service code ...
In the main function, configure the HTTP server to serve static files by:
http.FS
instance from the embedded StaticFS
using http.FS(web.StaticFS)
New
functionFiles
in the designThe file system instance provides access to the embedded files while maintaining proper file system semantics and security.
func main() {
// Other setup code...
mux := goahttp.NewMuxer()
server := genhttp.New(
endpoints,
mux,
goahttp.RequestDecoder,
goahttp.ResponseEncoder,
nil,
nil,
http.FS(web.StaticFS), // Pass the embedded file system
)
genhttp.Mount(mux, server)
// Start the server...
}
In this setup:
static
directory into the binary.Using the Files
function in Goa allows you to efficiently serve static content
in your services. By defining specific paths and file locations, you can manage
the delivery of static assets seamlessly. Ensure proper mapping of index files
and utilize embedded file systems for streamlined deployments.