Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use cache in MVC #850

Closed
Zeno-Code opened this issue Dec 31, 2017 · 5 comments
Closed

How to use cache in MVC #850

Zeno-Code opened this issue Dec 31, 2017 · 5 comments
Labels
good first issue A user wrote a good first issue with clear instructions 🤘 status:resolved

Comments

@Zeno-Code
Copy link
Contributor

First congratulations 10.0 release

I want to use "github.com/kataras/iris/cache" on MVC Methods

How to use it?

@kataras
Copy link
Owner

kataras commented Jan 1, 2018

Thank you @Zeno-Code

If you want to use it as middleware for the entire controller
you can use its router which is just a sub router to add it as you normally do with standard API:

I'll show you 4 different methods for adding a middleware into an mvc application,
all of those 4 do exactly the same thing, select what you prefer,
I prefer the last code-snippet when I need the middleware to be registered somewhere
else as well, otherwise I am going with the first one:

// 1
mvc.Configure(app.Party("/user"), func(m *mvc.Application) {
     m.Router.Use(cache.Handler(10*time.Second))
})
// 2
// same:
userRouter := app.Party("/user")
userRouter.Use(cache.Handler(10*time.Second))
mvc.Configure(userRouter, ...)
// 3
// same:
userRouter := app.Party("/user", cache.Handler(10*time.Second))
mvc.Configure(userRouter, ...)
// 4
// same:
app.PartyFunc("/user", func(r iris.Party){
    r.Use(cache.Handler(10*time.Second))
    mvc.Configure(r, ...)
})

If you want to use a middleware for a single route,
for a single controller's method that is already registered by the engine
and not by custom Handle (which you can add
the middleware there on the last parameter) and it's not depend on the Next Handler to do its job
then you just call it on the method:

var myMiddleware := myMiddleware.New(...) // this should return an iris/context.Handler

type UserController struct{}
func (c *UserController) GetSomething(ctx iris.Context) {
    // ctx.Proceed checks if myMiddleware called `ctx.Next()`
    // inside it and returns true if so, otherwise false.
    nextCalled := ctx.Proceed(myMiddleware)
    if !nextCalled {
        return
    }

    // else do the job here, it's allowed
}

And last, if you want to add a middleware on a specific method
and it depends on the next and the whole chain then you have to do it
using the AfterActivation like the example below:

package main

import (
	"time"

	"github.com/kataras/iris"
	"github.com/kataras/iris/cache"
	"github.com/kataras/iris/mvc"
)

var cacheHandler = cache.Handler(10 * time.Second)

func main() {
	app := iris.New()
	// You don't have to use .Configure if you do it all in the main func
	// mvc.Configure and mvc.New(...).Configure() are just helpers to split
	// your code better, here we use the simplest form:
	m := mvc.New(app)
	m.Handle(&exampleController{})

	app.Run(iris.Addr(":8080"))
}

type exampleController struct{}

func (c *exampleController) AfterActivation(a mvc.AfterActivation) {
	// select the route based on the method name you want to
	// modify.
	index := a.GetRoute("Get")
	// just prepend the handler(s) as middleware(s) you want to use.
	// or append for "done" handlers.
	index.Handlers = append([]iris.Handler{cacheHandler}, index.Handlers...)
}

func (c *exampleController) Get() string {
	// refresh every 10 seconds and you will see different time output.
	now := time.Now().Format("Mon, Jan 02 2006 15:04:05")
	return "last time executed without cache: " + now
}

@kataras kataras added the good first issue A user wrote a good first issue with clear instructions label Jan 1, 2018
@Zeno-Code
Copy link
Contributor Author

Zeno-Code commented Jan 1, 2018

Thanks Reply.

If use
//1 //2 //3 //4
During caching Each page in the controller returns the same content

Use the AfterActivation
If I want to cache all methods of the controller
I need to add middleware for each method and write the same code
It is not elegant

@kataras
Copy link
Owner

kataras commented Jan 1, 2018

It returns the same content because of the cache implementation, it depends on the handler not the path itself, I will update it to be used more generally and not per-handler only and after that you will use the // 4 method and it will work like a charm, I show you the advanced AfterActivation because I though you're asking for a single method inside a controller. I'll notify you.

@kataras
Copy link
Owner

kataras commented Jan 1, 2018

@Zeno-Code I prepared an example, although it's simple but many may have this question because the previous implementation didn't have those features, here you're: https://github.com/kataras/iris/blob/master/_examples/mvc/middleware/main.go

var cacheHandler = cache.Handler(10 * time.Second)

func main() {
	app := iris.New()
	mvc.Configure(app, configure)
	app.Run(iris.Addr(":8080"))
}

func configure(m *mvc.Application) {
	m.Router.Use(cacheHandler)
	m.Handle(&exampleController{
		timeFormat: "Mon, Jan 02 2006 15:04:05",
	})
}

// [...]

Don't forget to upgrade using go get -u github.com/kataras/iris first.

@Zeno-Code
Copy link
Contributor Author

It worked. Very perfect, Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue A user wrote a good first issue with clear instructions 🤘 status:resolved
Projects
None yet
Development

No branches or pull requests

2 participants