### Quartz Grails Plugin Example Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single A comprehensive example of a Grails plugin descriptor class, including metadata like version, author, description, and SCM information. ```groovy package quartz import grails.plugins.Plugin import groovy.util.logging.Slf4j @Slf4j class QuartzGrailsPlugin extends Plugin { // the version or versions of Grails the plugin is designed for def grailsVersion = "3.0.0.BUILD-SNAPSHOT > *" // resources that are excluded from plugin packaging def pluginExcludes = [ "grails-app/views/error.gsp" ] def title = "Quartz" // Headline display name of the plugin def author = "Jeff Brown" def authorEmail = "zzz@yyy.com" def description = '''\ Adds Quartz job scheduling features ''' def profiles = ['web'] List loadAfter = ['hibernate3', 'hibernate4', 'hibernate5', 'services'] def documentation = "http://grails.org/plugin/quartz" def license = "APACHE" def issueManagement = [ system: "Github Issues", url: "http://github.com/grails3-plugins/quartz/issues" ] def developers = [ [ name: "Joe Dev", email: "joedev@gmail.com" ] ] def scm = [ url: "https://github.com/grails3-plugins/quartz/" ] Closure doWithSpring()...... ``` -------------------------------- ### Create a New Grails Application Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Initializes a new Grails project named 'helloworld' in the current directory. This command is the starting point for developing a new Grails application. ```bash grails create-app helloworld ``` -------------------------------- ### Basic XML Rendering using Grails Converters Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Demonstrates the fundamental way to render a 'book' object as XML using Grails converters. This is a basic example showing the underlying mechanism. ```groovy import grails.converters.* ... render book as XML // or render book as JSON ``` -------------------------------- ### Grails URI Versioning Example Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Demonstrates how to version APIs by mapping different URI paths to specific controller namespaces. This approach requires separate namespaces for each API version. ```Groovy """/books/v1"""(resources:"book", namespace:'v1') """/books/v2"""(resources:"book", namespace:'v2') ``` ```Groovy package myapp.v1 class BookController { static namespace = 'v1' } package myapp.v2 class BookController { static namespace = 'v2' } ``` -------------------------------- ### Installing Grails with SDKMAN Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/gettingStarted This code demonstrates how to install the latest version of Grails using the SDKMAN package manager. You can also specify a particular version for installation. ```bash sdk install grails # To install a specific version: # sdk install grails 4.1.3 ``` -------------------------------- ### Verifying Grails Installation Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/gettingStarted After installing Grails, this command can be used to verify the installation and check the installed version. It's a simple command-line check to ensure Grails is accessible. ```bash grails -version ``` -------------------------------- ### Grails Command Execution Example Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Demonstrates the basic syntax for invoking Grails commands. Grails searches for commands based on the application's profile, allowing for profile-specific command behaviors. ```shell grails <> ``` ```shell grails run-app ``` ```shell grails help ``` ```shell grails <>* <> <>* ``` ```shell $ grails dev run-app $ grails create-app books ``` ```shell grails war --non-interactive ``` -------------------------------- ### Container Renderer Interface Example (Grails) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Defines an example of a `ContainerRenderer` for lists of 'Book' objects. It specifies the target type, component type, MIME types, and the rendering logic. ```groovy class BookListRenderer implements ContainerRenderer { Class getTargetType() { List } Class getComponentType() { Book } MimeType[] getMimeTypes() { [ MimeType.XML] as MimeType[] } void render(List object, RenderContext context) { .... } } ``` -------------------------------- ### Packaging Grails Application for Specific Environments (CLI) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Shows command-line interface commands for building Grails applications for different environments. It includes examples for using preset environments like `test` and `prod` with the `war` command, as well as targeting custom environments using the `-Dgrails.env` flag. ```Shell grails test war grails -Dgrails.env=UAT run-app ``` -------------------------------- ### Grails Runtime Configuration (Groovy) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single This example demonstrates how to configure runtime settings in Grails using Groovy's ConfigSlurper syntax in the `application.groovy` file. Configuration values defined here are available to the Grails CLI. ```groovy grails { server { port = 8080 } } my.tmp.dir = "${userHome}/.grails/tmp" ``` -------------------------------- ### Declarative HTTP Client Example Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single An example of a declarative HTTP client interface using Micronaut's @Client annotation. This interface defines methods that will be implemented as HTTP calls at compilation time. ```APIDOC ## Declarative HTTP Client ### Description This section demonstrates how to define a declarative HTTP client interface using Micronaut's `@Client` annotation. The methods in this interface are compiled into actual HTTP calls, allowing for data-bound POGO/POJO return types without manual handling. ### Example Interface ```java package example.grails import io.micronaut.http.annotation.Get import io.micronaut.http.client.annotation.Client @Client("https://start.grails.org") interface GrailsAppForgeClient { @Get("/{version}/profiles") List profiles(String version) } ``` ### Usage To use the declared client, inject it into any bean using the `@Autowired` annotation: ```java @Autowired GrailsAppForgeClient appForgeClient List profiles(String grailsVersion) { respond appForgeClient.profiles(grailsVersion) } ``` ### Notes - HTTP client methods are annotated with the corresponding HTTP method (e.g., `@Get`, `@Post`). - For more details, refer to the Http Client section of the Micronaut user guide. ``` -------------------------------- ### Grails REST Controller Manual Implementation Setup Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Illustrates the initial steps for manually implementing REST controllers in Grails by creating a controller and adding necessary imports and transactional annotations. ```Bash $ grails create-controller book ``` ```Groovy import grails.gorm.transactions.* import static org.springframework.http.HttpStatus.* import static org.springframework.http.HttpMethod.* @Transactional(readOnly = true) class BookController { ... } ``` -------------------------------- ### Install Grails with SDKMAN Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Installs the latest stable version of Grails using the SDKMAN package manager. SDKMAN simplifies the management of multiple Grails versions. ```bash sdk install grails ``` -------------------------------- ### Grails: Scaffolding i18n Label Keys Example Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Provides specific examples of i18n keys generated by Grails scaffolding for a `Book` domain class. These keys are used to retrieve localized labels for the domain class and its fields. ```properties book.label = Libro ``` ```properties book.title.label = Título del libro ``` -------------------------------- ### Example HAL JSON Document Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single A sample JSON document adhering to the HAL specification, demonstrating links, embedded resources, and resource states. This format is commonly used for REST APIs following HATEOAS principles. ```json { "_links": { "self": { "href": "/orders" }, "next": { "href": "/orders?page=2" }, "find": { "href": "/orders{?id}", "templated": true }, "admin": [ { "href": "/admins/2", "title": "Fred" }, { "href": "/admins/5", "title": "Kate" } ] }, "currentlyProcessing": 14, "shippedToday": 20, "_embedded": { "order": [ { "_links": { "self": { "href": "/orders/123" }, "basket": { "href": "/baskets/98712" }, "customer": { "href": "/customers/7809" } }, "total": 30.00, "currency": "USD", "status": "shipped" }, { "_links": { "self": { "href": "/orders/124" }, "basket": { "href": "/baskets/97213" }, "customer": { "href": "/customers/12369" } }, "total": 20.00, "currency": "USD", "status": "processing" } ] } } ``` -------------------------------- ### Get Grails Version at Runtime Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Retrieves the version of the Grails framework running the application. This can be accessed either through the GrailsApplication metadata or the static GrailsUtil class. ```groovy def grailsVersion = grailsApplication.metadata.getGrailsVersion() ``` ```groovy import grails.util.GrailsUtil ... def grailsVersion = GrailsUtil.grailsVersion ``` -------------------------------- ### Versioning REST Resources Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Strategies for exposing different versions of REST resources simultaneously within a Grails application. ```APIDOC ## Versioning REST Resources Grails offers several approaches to version your REST API, allowing you to maintain multiple versions concurrently. Specific implementation details will depend on your chosen strategy (e.g., URI versioning, header versioning). ``` -------------------------------- ### Publish Grails Profile Locally Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Publish a customized Grails profile to your local repository using the `gradle install` command. This makes the profile available for use with the `grails create-app` command. ```bash $ gradle install ``` -------------------------------- ### Install Specific Grails Version with SDKMAN Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Installs a specific version of Grails, in this case, 4.1.3, using SDKMAN. This allows for precise version control when managing Grails installations. ```bash sdk install grails 4.1.3 ``` -------------------------------- ### Grails Runtime Configuration (YAML) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Runtime configuration in Grails is typically specified in YAML format within the `grails-app/conf/application.yml` file. This example shows basic server port configuration. ```yaml grails: server: port: 8080 ``` -------------------------------- ### Running Grails Application Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Demonstrates how to run a Grails application using the `run-app` command. It shows the default port and how to specify a custom port. Also includes interactive mode usage. ```bash grails run-app grails run-app -port=8090 ``` ```bash $ grails grails> run-app | Grails application running at http://localhost:8080 in environment: development grails> stop-app | Shutting down application... | Application shutdown. grails> run-app | Grails application running at http://localhost:8080 in environment: development ``` -------------------------------- ### Run Grails Application (for plugin testing) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Command to run a Grails application, useful for testing plugins that target the 'web' profile. ```bash grails run-app ``` -------------------------------- ### Grails REST Profile Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Information on creating Grails applications using the REST profile, which focuses on RESTful API development with specific dependencies and commands. ```APIDOC ## Grails REST Profile ### Description Grails 3.1 and later offer a tailored profile for building REST applications. This profile provides a focused set of dependencies and commands optimized for API development, defaulting to JSON views for responses. ### Creating a REST Application To start a new application with the REST profile, use the `--profile rest-api` flag: ```bash $ grails create-app my-api --profile rest-api ``` ### Features - **Commands**: Provides default commands for creating and generating REST endpoints. - **JSON Views**: Defaults to using JSON views (e.g., `*.gson` files in `grails-app/views`) for rendering responses. - **Reduced Plugins**: Includes fewer plugins compared to the default Grails profile, excluding GSP, Asset Pipeline, and other HTML-related plugins. ### Example Workflow Generating domain classes and REST endpoints: ```bash $ grails create-domain-class my.api.Book $ grails generate-all my.api.Book ``` This process generates a REST endpoint that produces JSON responses and configures functional and unit tests to target these endpoints by default. ``` -------------------------------- ### Build Grails Documentation (Gradle) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single This command uses Gradle to build the Grails user guide. The `-x apiDocs` flag is used to skip the generation of Groovydoc API documentation, which can speed up the build process. ```gradle $ ./gradlew publishGuide -x apiDocs ``` -------------------------------- ### Create Grails Application and Domain Class Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single This sequence of commands first creates a new Grails application named 'helloworld', changes the directory to the application's root, and then creates a new domain class named 'Book'. ```bash grails create-app helloworld cd helloworld grails create-domain-class book ``` -------------------------------- ### Create a Basic JSON View Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single This example demonstrates the syntax for creating a simple JSON view file with the `.gson` extension. It utilizes the implicit `json` variable, an instance of StreamingJsonBuilder, to define the JSON structure. ```groovy json { name "bob" } ``` -------------------------------- ### Requesting HAL JSON from Grails API Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single An example using `curl` to request HAL JSON format for a specific book resource from a Grails API. It demonstrates setting the `Accept` header to `application/hal+json` and the expected HTTP response. ```bash $ curl -i -H "Accept: application/hal+json" http://localhost:8080/books/1 HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Type: application/hal+json;charset=ISO-8859-1 { "_links": { "self": { "href": "http://localhost:8080/books/1", "hreflang": "en", "type": "application/hal+json" } }, "title": "\"The Stand\"" } ``` -------------------------------- ### Grails Controller Action Chaining Example Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Demonstrates how to chain controller actions in Grails to pass model data from one action to the next. The 'chainModel' map is used to access data in subsequent actions. ```Groovy class ExampleChainController { def first() { chain(action: second, model: [one: 1]) } def second () { chain(action: third, model: [two: 2]) } def third() { [three: 3]) } } class ChainController { def nextInChain() { def model = chainModel.myModel ... } } chain(action: "action1", model: [one: 1], params: [myparam: "param1"]) ``` -------------------------------- ### Grails Console Command Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Presents the command to launch the Grails interactive console. This environment allows for testing GORM operations and other Grails features dynamically. ```shell grails console ``` -------------------------------- ### Configure settings.gradle for Inline Plugins (Grails 3) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Similar to the general multi-project setup, this configures `settings.gradle` to include both the application and plugin, achieving the effect of inline plugins as seen in older Grails versions. ```gradle include 'myapp', 'myplugin' ``` -------------------------------- ### Customizing Link Rendering in HAL Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Learn how to customize the generation of HATEOAS links within HAL responses by using the `link` method on domain objects. ```APIDOC ## Customizing Link Rendering in HAL ### Description Customize HATEOAS link rendering by using the `link` method within your controller actions to add specific transitions available to the client. ### Method POST, PUT, DELETE, GET (within controller actions) ### Endpoint Variable (depends on controller action) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None (parameters are within the `link` method call) ### Request Example ```groovy def show(Book book) { book.link rel:'publisher', href: g.createLink(absolute: true, resource:"publisher", params:[bookId: book.id]) respond book } ``` ### Response #### Success Response (200) HAL JSON response including the customized link. #### Response Example ```json { "_links": { "self": { "href": "http://localhost:8080/books/1", "hreflang": "en", "type": "application/vnd.books.org.book+json" }, "publisher": { "href": "http://localhost:8080/books/1/publisher", "hreflang": "en" } }, "title": "\"The Stand\"" } ``` ``` -------------------------------- ### Example Atom Feed XML Structure Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Illustrates the standard XML structure for an Atom feed, including elements like 'title', 'link', 'updated', 'author', 'id', and 'entry'. This serves as a reference for understanding the expected output format when Atom support is enabled in Grails. ```xml Example Feed 2003-12-13T18:30:02Z John Doe urn:uuid:60a76c80-d399-1d9-b93C-0003939e0af6 Atom-Powered Robots Run Amok urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a 2003-12-13T18:30:02Z Some text. ``` -------------------------------- ### Clone Grails Documentation Repository (Git) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single This command clones the Grails documentation source code from GitHub. This is the first step if you intend to make significant changes or build the documentation locally. ```git $ git clone https://github.com/grails/grails-doc/ $ cd grails-doc ``` -------------------------------- ### Creating a New Grails Application Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/gettingStarted This command initiates the creation of a new Grails application named 'helloworld'. It utilizes the `create-app` command provided by the Grails CLI. After creation, you navigate into the application directory. ```bash grails create-app helloworld cd helloworld ``` -------------------------------- ### Create a Grails Profile Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Use the `grails create-profile` command to generate a new, empty profile that extends the base profile. This command creates a directory for the profile where it is executed. ```bash $ grails create-profile mycompany ``` -------------------------------- ### Extending RestfulController Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Demonstrates how to extend Grails' `RestfulController` to customize RESTful API endpoints, including handling nested resources. ```APIDOC ## Extending the RestfulController super class ### Description This section explains how to extend the `grails.rest.RestfulController` class to customize API logic and actions. It includes examples of overriding methods for specific behaviors, such as handling nested resources. ### Method Various (GET, POST, PUT, DELETE) ### Endpoint Examples - `/books` (index, save) - `/books/${id}` (show, update, delete) - `/authors/books` (for nested resources) ### Controller Action Mapping | HTTP Method | URI | Controller Action | |-------------|------------------|-------------------| | GET | /books | index | | GET | /books/create | create | | POST | /books | save | | GET | /books/${id} | show | | GET | /books/${id}/edit| edit | | PUT | /books/${id} | update | | DELETE | /books/${id} | delete | *Note: `create` and `edit` actions are primarily for HTML interfaces.* ### Example: Nested Resource Handling #### Method GET, POST, PUT, DELETE #### Endpoint `/authors/${authorId}/books` #### Description This example shows how to override the `queryForResource` method to correctly retrieve books associated with a specific author. #### Controller Example ```groovy class BookController extends RestfulController { static responseFormats = ['json', 'xml'] BookController() { super(Book) } @Override protected Book queryForResource(Serializable id) { Book.where { id == id && author.id == params.authorId }.find() } } ``` ### Response Example (Varies based on the action and resource) ``` -------------------------------- ### Create Application and Domain Class (Grails) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/gettingStarted Demonstrates creating a new Grails application named 'helloworld' and then creating a domain class named 'Book' within that application. This involves using Grails command-line targets. ```shell grails create-app helloworld cd helloworld grails create-domain-class book ``` -------------------------------- ### Run Grails Application on a Different Port (CLI) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single This command shows how to start the Grails application server on a non-default port, which is useful if the default port (e.g., 8080) is already in use. It accepts any valid port number within the typical range. ```bash grails> run-app -port=9090 ``` -------------------------------- ### Atom Support Configuration Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Configure your Grails application to render responses in Atom format by defining custom Atom renderers. ```APIDOC ## Atom Support Configuration ### Description Enable Atom rendering for your REST API by defining custom `AtomRenderer` and `AtomCollectionRenderer` beans. ### Method Configuration ### Endpoint N/A ### Parameters #### Request Body - **beans** (Map) - Required - Grails beans configuration. - **halBookRenderer** (AtomRenderer) - Configures Atom rendering for a single `Book` instance. - **halBookListRenderer** (AtomCollectionRenderer) - Configures Atom rendering for a collection of `Book` instances. ### Request Example ```groovy import grails.rest.render.atom.* beans = { halBookRenderer(AtomRenderer, rest.test.Book) halBookListRenderer(AtomCollectionRenderer, rest.test.Book) } ``` ### Response #### Success Response (200) Atom XML feed representing the requested resources. #### Response Example ```xml Example Feed 2003-12-13T18:30:02Z John Doe urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6 Atom-Powered Robots Run Amok urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a 2003-12-13T18:30:02Z Some text. ``` ``` -------------------------------- ### Grails Create Domain Class Command Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Shows the command-line interface command to generate a new domain class named 'Person' within the 'helloworld' package. This command simplifies the initial setup of domain models. ```shell grails create-domain-class helloworld.Person ``` -------------------------------- ### Grails Command Line Examples Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/plugins Examples of Grails commands for listing plugins and retrieving plugin information from the central repository. These commands help manage and inspect available plugins. ```bash grails list-plugins grails plugin-info [plugin-name] ``` -------------------------------- ### Versioning with the Accept-Version header Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single This strategy allows clients to specify the desired API version via the `Accept-Version` header, keeping the base URI consistent across versions. ```APIDOC ## Versioning with the Accept-Version header ### Description Clients specify the desired API version using the `Accept-Version` header. The URL mappings are defined with a `version` attribute. ### Method GET ### Endpoint `/books` ### Query Parameters - **Accept-Version** (string) - Required - The version of the API to use (e.g., "1.0", "2.0"). ### Request Example ```bash $ curl -i -H "Accept-Version: 1.0" -X GET http://localhost:8080/books ``` ### Response Example (Depends on the version specified in the header) ``` -------------------------------- ### Run Grails Application Locally Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Commands to run a Grails application during development using either the Grails CLI or Gradle Wrapper. Allows for specifying the environment via system properties. ```bash grails prod run-app ./gradlew bootRun ./gradlew -Dgrails.env=prod bootRun ``` -------------------------------- ### Versioning using the URI Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single This method involves defining separate URI namespaces for different API versions. It's a straightforward approach but can lead to URI bloat. ```APIDOC ## Versioning using the URI ### Description This approach uses the URI to version APIs by defining distinct URL mappings for each version. For example, `/books/v1` and `/books/v2`. ### Method Not applicable (URI-based versioning). ### Endpoint Examples - `/books/v1` - `/books/v2` ### Request Example ``` GET /books/v1 ``` ### Response Example (Depends on the controller implementation for each version) ``` -------------------------------- ### Grails: Defining Localized Messages Properties Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Provides an example of how to define localized messages in a properties file. The key `my.localized.content` is used in the GSP, and the value can include placeholders for arguments. ```properties my.localized.content=Hola, me llamo John. Hoy es domingo. ``` ```properties my.localized.content=Hola, me llamo {0}. Hoy es {1}. ``` -------------------------------- ### Mapping RESTful Resources in Grails Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Shows how to create RESTful URL mappings in Grails using the `resources` parameter. This automatically maps standard HTTP methods to controller actions. ```groovy package mypackage class UrlMappings { static mappings = { "/books"(resources: 'book') "/books"(resources: 'book', excludes: ['delete', 'update']) "/books"(resources: 'book', includes: ['index', 'show']) } } ``` -------------------------------- ### Environment-Aware DataSource Configuration (Groovy) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Demonstrates how to define a base DataSource configuration and then override specific settings for different environments like production. This allows for environment-specific database URLs and other parameters. ```Groovy dataSource { pooled = true driverClassName = "com.mysql.jdbc.Driver" dialect = org.hibernate.dialect.MySQL5InnoDBDialect // other common settings here } environments { production { dataSource { url = "jdbc:mysql://liveip.com/liveDb" // other environment-specific settings here } } } ``` -------------------------------- ### Grails Controller for Lists of Command Objects Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single This example demonstrates how to handle a command object that contains a list of other command objects. The 'AuthorCommand' includes a list of 'BookCommand' objects. This functionality is supported for both GSP forms and JSON submissions, enabling complex data structures to be bound. ```groovy class DemoController { def createAuthor(AuthorCommand command) { // ... } class AuthorCommand { String fullName List books } class BookCommand { String title String isbn } } ``` ```html
``` ```json { "fullName": "Graeme Rocher", "books": [{ "title": "The Definitive Guide to Grails", "isbn": "1111-343455-1111" }, { "title": "The Definitive Guide to Grails 2", "isbn": "1111-343455-1112" }], } ``` -------------------------------- ### Navigate to Grails Application Directory Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Changes the current directory to the newly created Grails application's root folder, 'helloworld'. This is a standard command for moving between directories in a terminal. ```bash cd helloworld ``` -------------------------------- ### Grails Accept-Version Header Versioning Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Shows how to version APIs using the 'Accept-Version' header. URL mappings are defined with version constraints, and clients specify the desired version in the request header. ```Groovy """/books"""(version:'1.0', resources:"book", namespace:'v1') """/books"""(version:'2.0', resources:"book", namespace:'v2') ``` ```Bash $ curl -i -H "Accept-Version: 1.0" -X GET http://localhost:8080/books ``` -------------------------------- ### Recommended JVM Flags for Grails Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/gettingStarted Provides recommended JVM flags for running Grails applications in production containers. These flags focus on server performance (`-server`), heap size (`-Xmx`), and permanent generation size (`-XX:MaxPermSize`). ```shell -server -Xmx768M -XX:MaxPermSize=256m ``` -------------------------------- ### Grails Interactive Mode Commands Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single After creating a profile directory and entering interactive mode, a set of commands become available for managing profiles, such as creating commands, features, generators, and templates. ```bash $ cd mycompany $ grails | Enter a command name to run. Use TAB for completion: grails> create-command create-creator-command create-feature create-generator-command create-gradle-command create-template ``` -------------------------------- ### Grails GORM: Get Person by ID Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Shows how to retrieve a 'Person' object from the database using its unique identifier (ID) with the Person.get() method. It also includes an assertion to verify the retrieved ID. ```Groovy def p = Person.get(1) assert 1 == p.id ``` -------------------------------- ### Install Local Grails Plugin and Declare Dependency Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Commands and configuration to install a local Grails plugin into the Maven cache and declare it as a dependency in a Grails application's build.gradle file. ```bash grails install ``` ```groovy repositories { ... mavenLocal() } ... compile "org.grails.plugins:quartz:0.1" ``` -------------------------------- ### Publish Grails Profile to Bintray Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single This command initiates the process of publishing a configured Grails profile to Bintray. After execution, the profile will be uploaded, and you can then request its inclusion in the Grails profiles repository. ```bash $ gradle publishProfile ``` -------------------------------- ### Escaped XSS Attack - Nullified Javascript Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Shows the result of properly escaping the malicious Javascript code from the previous example. The browser renders the script as text instead of executing it, preventing the XSS attack. ```html <script>alert('Got ya!');</script> ``` -------------------------------- ### Grails Eager Fetching Solution for LazyInitializationException Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Presents a solution to the LazyInitializationException by implementing eager fetching for the `books` association in the `AuthorService`. This ensures that the associated books are queried and loaded when the `Author` is retrieved, preventing the exception. ```groovy class AuthorService { ... // other methods void updateAge(id, int age) { def author = Author.findById(id, [fetch:[books:"eager"]]) // ... rest of the method } } ``` -------------------------------- ### Run Grails Tests Command Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/gettingStarted Executes all unit and integration tests for a Grails application. Tests are typically located in the `src/test/groovy` directory and are automatically created by `create-*` commands. ```bash grails test-app ``` -------------------------------- ### Configuring Test Task for System Properties Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Shows how to configure the Gradle `test` task to include system properties, ensuring that tests can access external configuration values. ```Gradle test { systemProperties = System.properties } ``` -------------------------------- ### Grails AngularJS Profile Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Details about the Grails AngularJS profile, designed for applications with AngularJS, inheriting features from the REST profile and adding specific commands for Angular development. ```APIDOC ## Grails AngularJS Profile ### Description Since Grails 3.1, the AngularJS profile enables the creation of Grails applications specifically for AngularJS development. This profile inherits all features from the REST profile and adds commands and configurations for managing client-side Angular dependencies and execution. ### Creating an AngularJS Application To initiate an application with the AngularJS profile, use the `--profile angularjs` flag: ```bash $ grails create-app my-api --profile angularjs ``` ### Features - **AngularJS Commands**: Includes commands like `create-ng-component`, `create-ng-controller`, `create-ng-directive`, `create-ng-domain`, `create-ng-module`, and `create-ng-service`. - **Gradle Plugins**: Integrates Gradle plugins for managing client-side dependencies and executing client-side unit tests. - **Asset Pipeline**: Utilizes Asset Pipeline plugins to streamline development. - **GSP Support**: Includes GSP support for rendering the index page, as the profile is built around the Asset Pipeline. ### Project Structure and Commands Commands like `create-ng-*` automatically manage module creation and file placement. For example: - `create-ng-controller foo` creates `fooController.js` in `grails-app/assets/javascripts/${default package name}/controllers`. - `create-ng-domain foo.bar` creates `Bar.js` in `grails-app/assets/javascripts/foo/domains` and ensures the 'foo' module exists. - `create-ng-module foo.bar` creates `foo.bar.js` in `grails-app/assets/javascripts/foo/bar`. - `create-ng-service foo.bar --type constant` creates `bar.js` in `grails-app/assets/javascripts/foo/services` (with options for `service`, `factory`, `value`, `provider`, `constant`). ### Configuration - The default directory for Angular assets is `grails.codegen.angular.assetDir`. You can modify this in your configuration. - Skeleton unit test files are generated under `src/test/javascripts` for each create command. ``` -------------------------------- ### Create Grails App and Plugin using Grails CLI Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/plugins This command-line snippet demonstrates how to create a new Grails application and a Grails plugin using the Grails CLI. These are the initial steps for setting up a multi-project build. ```bash $ grails create-app myapp $ grails create-plugin myplugin ``` -------------------------------- ### Customizing Servlets with Spring Boot's ServletRegistrationBean Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Allows for detailed customization of a Servlet instance using Spring Boot's `ServletRegistrationBean`. This method provides more control over servlet configuration, such as `loadOnStartup`. ```groovy Closure doWithSpring() {{ myServlet(ServletRegistrationBean, new MyServlet(), "/myServlet/*") {{ loadOnStartup = 2 }} }} ``` -------------------------------- ### Generate Controller and Views for Grails Domain Class Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single This Grails command generates a controller, its associated unit test, and the necessary views for a given domain class ('helloworld.Book'). This is part of the scaffolding feature to quickly build application interfaces. ```bash grails generate-all helloworld.Book ``` -------------------------------- ### Configuring BootRun Task for System Properties Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Provides Gradle configuration for the `bootRun` task to ensure system properties are available when running the Grails application, which is necessary for external configuration to be read. ```Gradle bootRun { systemProperties = System.properties } ``` -------------------------------- ### XSS Attack Example - Malicious Javascript Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Illustrates a typical Cross-Site Scripting (XSS) attack vector where malicious Javascript code is injected into a form. This code, if not escaped, would execute in the user's browser. ```html ``` -------------------------------- ### Configuring Application and JVM Arguments for Gradle bootRun Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Illustrates how to pass JVM arguments and application arguments to the `bootRun` task in `build.gradle`. This allows overriding configuration options and setting specific JVM behaviors. ```groovy bootRun{ bootRun { jvmArgs('-Dspring.output.ansi.enabled=always') args('--app.foo=bar','--app.bar=foo') // Override the `app.foo` and `app.bar` config options (`grailsApplication.config`) } } ``` -------------------------------- ### Grails Custom Script: Hello World Example Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/commandLine A simple Groovy script for Grails that prints 'Hello World' to the console. It includes a description method for `grails help`. ```groovy description "Example description", "grails hello-world" println "Hello World" ``` -------------------------------- ### Grails Domain Class Definition Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Illustrates the basic structure of a Grails domain class, including package declaration and property definitions. It shows how to define String, Integer, and Date properties. ```Groovy package helloworld class Person { String name Integer age Date lastVisit } ``` -------------------------------- ### Targeting Test Phases in Grails Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Shows how to execute tests based on their defined phases, specifically 'unit' and 'integration'. This allows for focused test execution depending on the type of testing required. ```grails grails test-app -unit grails test-app -integration ``` -------------------------------- ### Create Application with Custom Profile Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Generate a new Grails application using a specific profile by providing the profile name to the `grails create-app` command. This applies the dependencies and features defined in the profile. ```bash $ grails create-app myapp --profile mycompany ``` -------------------------------- ### Grails Artefact API: Getting Artefact Classes by Type Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Retrieve all classes of a specific artefact type (e.g., controller, service) from the Grails application. The returned objects are GrailsClass instances providing metadata about the artefact. ```Groovy for (cls in grailsApplication.Classes) { ... } ``` -------------------------------- ### Initialize Grails Project Documentation Template Source: https://grails.github.io/legacy-grails-doc/4.1.3/ref/Command%20Line/docs This command initializes a template project for documentation using the '--init' argument. This is useful for setting up a new documentation structure. ```bash gradle docs --init ``` -------------------------------- ### Generate Controller, Views, and Test (Grails) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/gettingStarted Uses the `generate-all` command to automatically generate a controller, its associated views, and a unit test for a given domain class (e.g., `helloworld.Book`). This command accelerates development by providing a basic CRUD interface. ```shell grails generate-all helloworld.Book ``` -------------------------------- ### Configure Read-Only REST Resource Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single This snippet shows how to configure a REST resource to be read-only by setting the `readOnly` attribute to `true` in the @Resource transformation. This prevents `POST`, `PUT`, and `DELETE` operations, allowing only `GET` requests. ```groovy import grails.rest.* @Resource(uri='/books', readOnly=true) class Book { ... } ``` -------------------------------- ### Implementing GrailsConfigurationAware for Configuration Access Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Shows an alternative approach to accessing configuration by implementing the `GrailsConfigurationAware` interface. This allows configuration properties to be set on class instance properties during initialization. ```Groovy import grails.core.support.GrailsConfigurationAware class MyService implements GrailsConfigurationAware { String recipient String greeting() { return "Hello ${recipient}" } void setConfiguration(Config config) { recipient = config.getProperty('foo.bar.hello') } } ``` -------------------------------- ### HAL Renderer Configuration with Custom MIME Types Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Configure HAL (Hypertext Application Language) renderers to utilize your custom MIME types for both single resource instances and collections. ```APIDOC ## HAL Renderer Configuration with Custom MIME Types ### Description Override the default renderers to provide HAL responses using your custom MIME types for single resources and collections. ### Method Configuration ### Endpoint N/A ### Parameters #### Request Body - **beans** (Map) - Required - Grails beans configuration. - **halBookRenderer** (HalJsonRenderer) - Configures HAL rendering for a single `Book` instance with a specific MIME type. - **halBookListRenderer** (HalJsonCollectionRenderer) - Configures HAL rendering for a collection of `Book` instances with a specific MIME type. - **MimeType** (Object) - Represents a MIME type with versioning information. ### Request Example ```groovy import grails.rest.render.hal.* import grails.web.mime.* beans = { halBookRenderer(HalJsonRenderer, rest.test.Book, new MimeType("application/vnd.books.org.book+json", [v:"1.0"])) halBookListRenderer(HalJsonCollectionRenderer, rest.test.Book, new MimeType("application/vnd.books.org.booklist+json", [v:"1.0"])) } ``` ### Response #### Success Response (200) Customized HAL JSON response matching the configured MIME types. #### Response Example ```json { "_links": { "self": { "href": "http://localhost:8080/books/1", "hreflang": "en", "type": "application/vnd.books.org.book+json" } }, "title": "\"The Stand\"" } ``` ``` -------------------------------- ### Accessing Original Input Value After Data Binding Errors (Groovy) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Illustrates how to check for and retrieve the original input value after data binding errors occur. This example checks if the `login` field has errors and prints the `rejectedValue` if it does. ```Groovy if (user.hasErrors()) { if (user.errors.hasFieldErrors("login")) { println user.errors.getFieldError("login").rejectedValue } } ``` -------------------------------- ### Creating Grails Command Line Scripts (Code Generation) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Demonstrates how to create a code generation script for Grails 3.0. This script is placed in `src/main/scripts` and can be used to automate artifact creation within a project. ```bash # Directory structure for additional scripts + src/main/scripts + grails-app + controllers + services + etc. ``` -------------------------------- ### Configuring Resource Formats Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Customize the default response format (JSON or XML) and specify supported formats for REST resources using the `formats` attribute in the `@Resource` transformation. ```APIDOC ## Configuring Response Formats To prioritize JSON responses, set the `formats` attribute in the `@Resource` transformation: ```groovy import grails.rest.* @Resource(uri='/books', formats=['json', 'xml']) class Book { String title static constraints = { title blank:false } } ``` This ensures that JSON will be preferred over XML when both are supported. The available formats are defined in `grails.mime.types` in `application.groovy`. ``` -------------------------------- ### Grails Build Configuration (Gradle) Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Grails build configuration is managed via Gradle and the `build.gradle` file. This snippet shows a typical dependency declaration. ```gradle dependencies { implementation "org.grails:grails-plugin-rest:4.1.3" } ``` -------------------------------- ### Defining Basic URL Mappings in Grails Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Shows how to define URL mappings in Grails' `UrlMappings.groovy` file to map URLs to controller actions. Supports direct mapping and block syntax. ```groovy package mypackage class UrlMappings { static mappings = { "/product"(controller: "product", action: "list") "/product"(controller: "product") // Maps to default action "/product" { controller = "product" action = "list" } } } ``` -------------------------------- ### Content Negotiation with Accept Header Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Utilize Grails' content negotiation features to receive responses in a specific format (e.g., JSON) by setting the `Accept` header in the request. ```APIDOC ## Content Negotiation To receive a JSON response using the `Accept` header, send a request with `Accept: application/json`. ### Example using `curl`: ```bash curl -i -H "Accept: application/json" localhost:8080/books/1 ``` This leverages Grails' built-in content negotiation to serve the appropriate response format. ``` -------------------------------- ### Interactive Grails Console Commands Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/gettingStarted Demonstrates running a Grails application in interactive mode using the Grails console. This mode allows for quicker container restarts and features commands like 'run-app' and 'stop-app' for managing the application lifecycle. ```bash $ grails grails> run-app | Grails application running at http://localhost:8080 in environment: development grails> stop-app | Shutting down application... | Application shutdown. grails> run-app | Grails application running at http://localhost:8080 in environment: development ``` -------------------------------- ### Grails Command Invocation Examples Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/commandLine Demonstrates how to invoke Grails commands, including specifying an environment, a target command, and arguments. Also shows examples of application creation and listing available commands. ```bash grails <> grails run-app grails help grails <>* <> <>* $ grails dev run-app $ grails create-app books ``` -------------------------------- ### Grails: Scaffolding i18n Labels for Domain Classes Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single Explains how Grails scaffolding templates utilize internationalization for domain class labels and field names. Examples show the naming convention for keys used in message properties files. ```groovy class Book { String title } ``` -------------------------------- ### Default JSON Validation Error Response Source: https://grails.github.io/legacy-grails-doc/4.1.3/guide/single This example demonstrates the default JSON response when a validation error occurs during a POST request in Grails. It shows a 422 Unprocessable Entity status with an 'errors' object detailing the validation failure. ```shell $ curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X POST -d "" http://localhost:8080/books HTTP/1.1 422 Unprocessable Entity Server: Apache-Coyote/1.1 Content-Type: application/json;charset=ISO-8859-1 { "errors": [ { "object": "rest.test.Book", "field": "title", "rejected-value": null, "message": "Property [title] of class [class rest.test.Book] cannot be null" } ] } ```