apache / apache/grails-core

model not available in interceptor when using render in controller for a rest-api profile Grails 4 application

Open
#12,081 0 comments 0 reactions 0 assignees View on GitHub
type: bug
Dominant language
Groovy
Stars
2.9k
Forks
975
Avg merge
1d 22h
Merged PRs (30d)
92

Description

### Steps to Reproduce

Create an app with the rest-api profile

```
% grails --version
| Grails Version: 4.1.0.M5
| JVM Version: 11.0.12
grails create-app example.grails.interceptorsbug --profile=rest-api
```

Given the following controller:

```groovy
package example.grails

class BooksController {
def show(String isbn) {
[book: new Book(isbn, "Building Microservices")]
}

def showrender(String isbn) {
render template: '/books/book', model: [book: new Book(isbn, "Building Microservices")]
}
}
```

and the following `UrlMappings.groovy` modifications:

```groovy
package example.grails

class UrlMappings {
static mappings = {
...
get "/books/$isbn"(controller: 'books', action: 'show')
get "/booksrender/$isbn"(controller: 'books', action: 'showrender')
...
}
}

```

and the POGO:

```groovy
package example.grails

import groovy.transform.Canonical
import groovy.transform.CompileStatic

@Canonical
@CompileStatic
class Book {
String isbn
String name

}
```

JSON Views:

`grails-app/views/books/_books.gson`

```groovy
import example.grails.Book

model {
Book book
}
json {
isbn book.isbn
name book.name
}
```

`grails-app/views/books/show.gson`

```groovy
import example.grails.Book
model {
Book book
}
json tmpl.book(book)
```

With an Interceptor such as:

```groovy
package example.grails

import groovy.transform.CompileStatic

@CompileStatic
class BookShowInterceptor {
BookShowInterceptor() {
match(controller:"books", action:"show")
match(controller:"books", action:"showrender")
}

boolean after() {
if (model?.book) {
final Book book = (Book) model.book
println "intercepted book with ${book.isbn}"
} else {
println "no book found in model"
}
true
}
}
```

If you execute the app:

```./gradlew bootRun```

If you do the cURL command:

```
% curl -i localhost:8080/booksrender/1491950358
```

The console output shows:

```
no book found in model
```

If you do the cURL command:

```
% curl -i localhost:8080/books/1491950358
```

The console output shows:

```
intercepted book with 1491950358
```

### Expected Behaviour

I expected the model to be present for both actions.

### Actual Behaviour

It is not present for the action which uses `render`

### Environment Information

- **Operating System**: MacOS BigSure
- **Grails Version:** 4.1.0.M5
- **JDK Version:** 11

Contributor guide

Open the contributing guide

Research direction

Reproduce the issue with the rest-api profile using BooksController.showrender, BookShowInterceptor.after, and the shown URL mappings, then run ./gradlew bootRun and both curl requests. Trace how render and the interceptor lifecycle handle the model; done means the interceptor sees the Book model for both /books/$isbn and /booksrender/$isbn.

Written by the indexing model from the issue text.

Assessment

Tech stack
groovy
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.