Gregg
Gregg

Reputation: 35864

Validating RESTful URLs for every request the DRY way

Our Grails 2.4.4 application is using RESTful URLs throughout. Given the following URL:

/stores/123/products/456

I'd like to validate that there is a store with an ID of 123, and if not, redirect to a 404 on every request to the Product controller. I don't want to have to put that store lookup code in each action method, nor do I want to create a controller base class, because then I have to put a method call in every action method.

Can this be done with a interceptor somehow?

Upvotes: 1

Views: 213

Answers (2)

dmahapatro
dmahapatro

Reputation: 50245

Interceptors are introduced in Grails 3.0. You would need filters in Grails 2.4.4.

before = { } is what will be needed here.

Also look at the docs which variable are available to filters by default (eg: params, request, response etc). If this is still unclear, I can add an answer as an example. But I hope docs will be self explanatory. As an example i would do it as

class EntityCheckFilters {
    def filters = {
        storeExistCheck( controller:'product' ) {
            before = {
               if ( !params.storeId || !Store.exists( params.sotreId as Long ) ) {
                    response.sendError(404)
                    // or for example if you have a separate action to handle 404
                    // redirect(action: 'handle404')

                    // this is important, 
                    // because we do not want to pass through with the original call
                    return false 
               }
            }
        }
    }
}

Upvotes: 1

dsharew
dsharew

Reputation: 10665

I think you can do this using:

  1. URL Mapping
  2. Filters

But I dont think putting a logic (checking if there is a valid store with the given id) in URL Mapping is good idea, so better to use Filters.

So you url mapping will look like this:

"/stores/$storeId/products/$productId" (controller = "product")

And your filter:

class YourFilterNameFilters {


    def filters = {
        secureReports(controller:'*', action:'*') {
            before = {

               if(parmas.controller == "product" && params.storeId){
                     Store store = Store.get(params.sotreId)
                    if(!store){
                        response.sendError(404)
                     }
                 }
           }
      }
}

Upvotes: 0

Related Questions