I'm playing around with Grails 3, specifically REST Api support features.
One of the new features (coming from 2.5.5) is the new gson views.
I'm trying to follow the documentation, but my template seems to be ignored.
I've made my sample project available on github, but the important bits are here:
My UrlMapping
:
"/books"(resources: "book")
My Book
domain class:
class Book {
String title
static constraints = {
title(blank: false)
}
}
From my BookController
:
def show(Book book) {
respond new Book(id: 1, title: "Foo bar")
}
My show.gson
:
model {
Book book
}
json g.render(book)
Finally, my book/_book.gson
:
json {
title "Book Template"
}
What I see in the browser with this setup is:
{"title":"Foo bar"}
I went looking online for some examples and found this one
Which leads me to believe that Grails should ignore or bypass my show.gson
and just render my _book.gson
, but that isn't happening. I tried deleting my show.gson
, but then I got a blank page.
The Grails documentation leads me to believe that my show.gson
should render my _book.gson
template, but that isn't happening either.
I've tried cleaning and re-running, but I get the same result.
I was able to get it to work using a fully qualified template name:
"Fixed" show.gson
:
model {
Book book
}
json g.render(template: "/book/book", model: [book: book])
Workable, but not ideal, and not what's in the docs.
I'm not sure what I'm doing wrong here, I must be missing something.
[UPDATED]
Since, you are learning, please follow along :). To do it the right way
grails create-app my-app-name --profile rest-api
cd my-app-name
grails create-domain-resource mochi.book
This will generate a domain class with the name book for you and annotate it with @Resource annotation. You can add your title field to this domain class
package mochiimport grails.rest.* @Resource(readOnly = false, formats = ['json', 'xml']) class Book { String title }
You don't need to define a save method in your controller, simply mark your domain class as a resource with @Resource, Grails will generate a controller for you with all the REST-API operations. When, you use the "create-domain-resource" above, the annotation should already be there for you, as I have show in my code snippet.
Moreover, you don't need to create a controller just to define a show method. Grails automatically creates a controller for any domain class marked with @Resource annotation. If you do want to create a controller, I recommend two options:
i. With the command:
grails create-restful-controller mochi.Book
This will create a restful controller for your book class in your controllers directory. This controller extends from a class called RestfulController, this class already defines methods to do all the RESTFUL-API operations, including show.
ii. With the command:
grails generate-controller mochi.Book
This will create a controller with all the RESTFUL-API operations. It will not extend any class, as all those operations will be defined directly in this class.
NB: It is rare that you may need to touch these operations. So I recommend the first option. It keeps your code simple and clean.
Use the command:
grails generate-views mochi.Book
This will create all the files and the template you are manually creating yourself.Including the _book template file, in the right directory. You can edit them from here, inside your views/book folder.
Try creating new projects and testing all these features, to know how they look like.
package stack1 import mochi.Book class BootStrap { def init = { servletContext -> new Book(title: "Languages").save() new Book(title: "Maths").save() } def destroy = { } }
This file is executed everytime your application starts
Check a screenshot of the location of my views
I hope this helps. Thank you...