github go-goyave/goyave v5.0.0-preview5
Pre-release v5.0.0-preview5

latest releases: v5.2.1, v5.2.0, v5.1.1...
pre-release10 months ago

Server options

When creating a new server with goyave.New(), you can now pass a goyave.Options structure that will override the default values. Currently, you can replace the automatically loaded config, the logger and provide a file system to load the language files. You can find out more about this in the section below.

Adding a structure as parameter is flexible from an API point of view, as more options can be added without breaking changes. For developers, it is easier to use and more intuitive than to manually replace those elements after creating the server. This also removes unnecessary startup operations in case developers want to replace those components.

This change is breaking compared to the preview pre-release version of the framework.

  • goyave.NewWithConfig() was removed, use goyave.New(goyave.Options{Config: cfg}) instead.
  • testutil.NewTestServerWithConfig(t, cfg, routeRegistrer) becomes testutil.NewTestServerWithOptions, options, routeRegistrer). By default, the test servers use osfs.FS.

File systems

All features using files in some way have been revisited and improved to take full advantage of the standard io/fs package. All future components of the framework will be designed with this in mind. The util/fsutil package now defines a few useful interfaces in addition to standard ones in io/fs.

  • fsutil.FS: combination of fs.ReadDirFS and fs.StatFS.
  • fsutil.WorkingDirFS
  • fsutil.MkdirFS
  • fsutil.WritableFS
  • fsutil.RemoveFS

The fsutil.Embed structure allows easy implementation of fs.StatFS on embed.FS:

//go:embed resources
var resources embed.FS

func main() {
    resourcesFS := fsutil.Embed{FS: resources}
}

A new package util/fsutil/osfs contains an implementation of the OS filesystem. This structure is just a proxy to the standard os package so it can be passed around as an interface parameter.

Below is a list of features that can now take advantage of this abstraction. These changes introduce breaking changes compared to the preview pre-release version of the framework.

  • auth.JWTService now takes a file system for loading the signing keys
    • auth.NewJWTService(config) becomes auth.NewJWTService(config, fs)
    • By default, and when added automatically by the JWTController, the service uses osfs.FS.
  • Language loading now takes a fsutil.FS parameter
    • lang.Languages.Load(language, path) becomes lang.Languages.Load(fs, language, path)
    • lang.Languages.LoadLoadAllAvailableLanguages() becomes lang.Languages.LoadLoadAllAvailableLanguages(fs)
    • lang.Languages.LoadDirectory(directory) becomes lang.Languages.LoadDirectory(fs, directory)
  • Response.File(path) and Response.Download(path, fileName) become Response.File(fs, path) and Response.Download(fs, path, fileName)
  • Router.Static(uri, directory, download) becomes Router.Static(fs, uri, directory, download)
  • fsutil.File.Save(path, name) becomes fsutil.File.Save(fs, path, name)
  • fsutil.GetMIMEType(file) becomes fsutil.GetMIMEType(fs, file)
  • fsutil.FileExists(file) becomes fsutil.FileExists(fs, file)
  • fsutil.IsDirectory(path) becomes fsutil.IsDirectory(fs, path)
  • fsutil.Delete(path) was removed. Use osfs.FS.Remove() instead.
  • testutil.WriteMultipartFile(writer, path, fieldName) becomes testutil.WriteMultipartFile(writer, fs, path, fieldName)
    • testutil.CreateTestFiles(file1, file2) becomes testutil.WriteMultipartFile(fs, file1, file2)

Using this abstraction is beneficial in many ways for maximum flexibility:

  • It is easily possible to serve remote resources, such as static assets stored on a cloud storage bucket
  • It is possible to take advantage of the embedding capabilities of Go, be it for language files, or static assets. Bundling your executable will require less external resources.

It is advised to expose the file systems through a service so all components have centralized and easy access to them.

Misc

  • Removed default values for database configuration. Previously, they were defaults for the MySQL DB engine. The framework had no reason assuming this engine should be the default.
  • New exported readonly field validation.Context.Invalid, making it easier to unit-test validators that use the now removed context.Valid() method.
  • In the log middleware, the slog attributes are ignored to reduce clutter. The message itself is enough.
  • The internal config loader has been refactored to use io/fs too so it's future-proof.
  • Avoid duplicate CORS middleware if the middleware is already defined as a global middleware.

Don't miss a new goyave release

NewReleases is sending notifications on new releases.