While developing a Grails application, what do you consider to be "best practices" and why? I'm not interested in a debate on best practices, but one or more statements backed up with a justification and/or a description of when the best practice applies and when it does not. I don't believe that there is one best way to develop Grails applications but that there are a number of guidelines that will lead to more maintainable applications with fewer bugs lurking in them.
My experience of Grails is that it offers so many capabilities that there is a temptation to use them all in a single application, which results in some of the worst spaghetti code that I have seen since I debugged a Fortran program with GOTO statements into and out of part of a DO loop.
We all know how Grails creates a place for domain classes, services, views, controllers, etc. What kind of functions belong in these places? What rules of thumb help you to do the right thing? What are Grails code smells?
Understand the Grails conventions. Grails is convention driven; and the conventions are how Grails can do a lot of its magic for you. Views should just be views. Controllers should just be controllers. Services and Model objects should contain all of the logic of your application. This means the when you click a link, or invoke an endpoint, you call into a Controller. The controller will invoke a service (which might in turn invoke other services) and give a concise response. The service will return model objects or data to the controller, which will simply render an appropriate response. Services are transactional, so anything that hits the database should go in a service.
Test. Test. Test some more. Having tests is the best way to ensure you can add functionality without breaking new functionality, i.e. that your project is maintainable.
Dependency Injection. You need to put your components in the appropriate grails-app/folder. Services go into the services folder. Controllers go into the controllers folder. If you have a Thing model object, and you need a controller and service for it, then your controller and service should be named ThingController and ThingService. To get the ThingService into your ThingController, put def thingService
in your controller, and grails will autowire it up for you. If you fail to follow naming conventions and the rules for where to put the various components, the autowiring might fail.
Understand the underlying technologies, namely Spring and Hibernate. You are going to run into issues modeling your domain objects and getting them to work together. Grails really is a high productivity framework, but if you don't understand how Hibernate works, you are going to get lost easily when trying to get your persistence to behave the way you want it.
Groovy is not Java. A lot of Java knowledge will serve you well. But Groovy is a dynamic language and Grails has its own set of gotchas that stem from Groovy. You will run into runtime issues around typing in Grails that you largely avoid with Java. Testing helps with this.
These things seem obvious, but many questions arise around these issues.