FAQs

How do I change the listen address?

If you’re using the Run method to start the web server, you may change the listen address using either the environment variable FLAMEGO_ADDR:

  1. export FLAMEGO_ADDR=localhost:8888

Or the variable arguments of the Run method:

  1. f.Run("localhost") // => localhost:2830
  2. f.Run(8888) // => 0.0.0.0:8888
  3. f.Run("localhost", 8888) // => localhost:8888

Alternatively, http.ListenAndServeFAQs - 图1open in new window or http.ListenAndServeTLSFAQs - 图2open in new window can also be used to change the listen address:

  1. http.ListenAndServe("localhost:8888", f)
  2. http.ListenAndServeTLS("localhost:8888", "certFile", "keyFile", f)

How do I do graceful shutdown?

The github.com/ory/gracefulFAQs - 图3open in new window package can be used to do graceful shutdown with the Flame instance:

  1. package main
  2. import (
  3. "net/http"
  4. "github.com/flamego/flamego"
  5. "github.com/ory/graceful"
  6. )
  7. func main() {
  8. f := flamego.New()
  9. ...
  10. server := graceful.WithDefaults(
  11. &http.Server{
  12. Addr: "0.0.0.0:2830",
  13. Handler: f,
  14. },
  15. )
  16. if err := graceful.Graceful(server.ListenAndServe, server.Shutdown); err != nil {
  17. // Handler error
  18. }
  19. }

How do I serve file downloads?

  1. import (
  2. "net/http"
  3. "net/url"
  4. "path/filepath"
  5. "github.com/flamego/flamego"
  6. "golang.org/x/exp/utf8string"
  7. )
  8. func main() {
  9. f := flamego.Classic()
  10. f.Get("/download", func(w http.ResponseWriter, r *http.Request) {
  11. fpath := "your filepath"
  12. filename := filepath.Base(fpath)
  13. if utf8string.NewString(filename).IsASCII() {
  14. w.Header().Set("Content-Disposition", `attachment; filename="`+filename+`"`)
  15. } else {
  16. w.Header().Set("Content-Disposition", `attachment; filename*=UTF-8''`+url.QueryEscape(filename))
  17. }
  18. http.ServeFile(w, r, fpath)
  19. })
  20. f.Run()
  21. }

How do I integrate into existing applications?

Because Flame instances implement the http.HandlerFAQs - 图4open in new window interface, a Flame instance can be plugged into anywhere that accepts a http.Handler.

Example: Integrating with net/http

Below is an example of integrating with the net/http router for a single route "/user/info":

  • Code
  • Test
  1. package main
  2. import (
  3. "log"
  4. "net/http"
  5. "github.com/flamego/flamego"
  6. )
  7. func main() {
  8. f := flamego.New()
  9. f.Get("/user/info", func() string {
  10. return "The user is Joe"
  11. })
  12. // Pass on all routes under "/user/" to the Flame isntance
  13. http.Handle("/user/", f)
  14. if err := http.ListenAndServe("0.0.0.0:2830", nil); err != nil {
  15. log.Fatalf("Failed to start server: %v", err)
  16. }
  17. }
  1. $ curl -i http://localhost:2830/user/info
  2. The user is Joe

Example: Integrating with Macaron

Below is an example of integrating with the Macaron router for a single route "/user/info":

  • Code
  • Test
  1. package main
  2. import (
  3. "log"
  4. "net/http"
  5. "github.com/flamego/flamego"
  6. "gopkg.in/macaron.v1"
  7. )
  8. func main() {
  9. f := flamego.New()
  10. f.Get("/user/info", func() string {
  11. return "The user is Joe"
  12. })
  13. // Pass on all routes under "/user/" to the Flame isntance
  14. m := macaron.New()
  15. m.Any("/user/*", f.ServeHTTP)
  16. if err := http.ListenAndServe("0.0.0.0:2830", m); err != nil {
  17. log.Fatalf("Failed to start server: %v", err)
  18. }
  19. }
  1. $ curl -i http://localhost:2830/user/info
  2. The user is Joe

What is the difference between inject.Invoker and inject.FastInvoker?

The inject.InvokerFAQs - 图5open in new window is the default way that the Flame instance uses to invoke a function through reflection.

In 2016, @tupuncoFAQs - 图6open in new window contributed a patchFAQs - 图7open in new window with the concept and the implementation of the inject.FastInvokerFAQs - 图8open in new window, which invokes a function through interface. The inject.FastInvoker is about 30% faster to invoke a function and uses less memory.

What is the idea behind this other than Macaron/Martini?

Martini brought the brilliant idea of build a web framework with dependency injection in a magical experience. However, it has terrible performance and high memory usage. Some people are blaming the use of reflection for its slowness and memory footprint, but that is not fair by the way, most of people are using reflections every single day with marshalling and unmarshalling JSON in Go.

Macaron achieved the reasonable performance and much lower memory usage. Unfortunately, it was not a properly designed product, or let’s be honest, there was no design. The origin of Macaron was to support the rapid development of the GogsFAQs - 图9open in new window project, thus almost all things were inherited from some other web frameworks at the time.

Absence of holistic architecture view and design principles have caused many bad decisions, including but not limited to:

All in all, Macaron is still an excellent web framework, and Flamego is just better as the successor. 🙂

Why the default port is 2830?

keyboard layout 2830