Custom services

    The Flame instance is building on top of the open in new window to provide service injections for your handlers. Both and flamego.Contextopen in new window have embeded the inject.TypeMapper that allow you to inject services at anywhere you want.

    The Map method is used to inject services (aka. map values to their own types), the injected service can be a concrete type () or an interface (io.Writeropen in new window):

    The MapTo method works similar to Map but instead of mapping values to their own types, it allows you to map values to interfaces:

    1. buf := &bytes.Buffer{}
    2. f := flamego.New()
    3. f.MapTo(buf, (*io.Writer)(nil))

    You may also use the MapTo method to transform interfaces to other interfaces:

    WARNING

    When you inject services to the Flame instance without attaching to any route, these injected services are considered as global services, which are available for all handlers of the Flame instance.

    There are two ways you can inject a global service, directly call Map or on the Flame instance, or through a using the Use method:

    1. db := database.New()
    2. f := flamego.New()
    3. // or
    4. f := flamego.New()
    5. f.Use(func(c flamego.Context) {
    6. db := database.New()
    7. c.Map(db)
    8. })

    When you inject services to a group of routes, these injected services are considered as group services, which are only available for all handlers within the group.

    You can only inject a group service through a group middleware:

    In the above example, the *database.User is only available to the group of routes on line 3 to 7. Trying to use it outside the group will cause panic as illustrated on line 14.

    You can only inject a route-level service through a :

    1. f := flamego.New()
    2. user := database.GetUser()
    3. c.Map(user)
    4. },
    5. f.Get("/settings", func(user *database.User) {
    6. ...
    7. }),
    8. )
    9. f.Get("/repo", func(user *database.User) {
    10. // This handler will cause panic because *database.User is not available
    11. })

    In the above example, the *database.User is only available to the route on line 7 to 9. Trying to use it in all other routes will cause panic as illustrated on line 11.

    Overriding services

    Injected services can be overridden when you’re not happy with the service functionality or behaviors provided by the other middleware.

    Here is an example of overriding a global service at the route level:

    When you run the above program and do curl http://localhost:2830/, the following content are printed to your terminal: