grailsjson-viewgrails3.2.0

Grails 3 gson views and domain class template


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.


Solution

  • [UPDATED]

    Since, you are learning, please follow along :). To do it the right way

    1. Create new project by running:

    grails create-app my-app-name --profile rest-api

    1. Navigate into your project folder:

    cd my-app-name

    1. Create a restful-domain-class called book:

    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 mochi

    import grails.rest.*
    
    @Resource(readOnly = false, formats = ['json', 'xml'])
    class Book {
    
        String title
    
    }
    

    1. 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.

    2. 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.

    1. Now with the views, I always start from where grails leave me :). Grails knows where to put stuff. To create views for your book domain, I don't recommend you do it manually. First of all, when you don't create any view, know that grails creates one for you at run-time. But as it seems, you want to edit this file. So let Grails generate them and then edit them from there. Fun, isn't it?

    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.

    1. Finally, how do you get data into your domain-class. There is a file inside grails-app/init/Bootsrap.groovy. Add your objects here, and there will be availale for you.
        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...