Session Notes – RESTful Grails

Presenter: Scott Davis
Author:

  • Groovy Recipes
  • GIS for Web Developers (all open source, REST based)
  • Groovy/Grails articles on IBM developerworks
    • Google “Mastering Grails” or “Practically Groovy”
  • Getting Started With Grails, 2d edition — free PDF on InfoQ available soon

RESTful Web Services in Grails

  • ebay
    • obviously have the web site, but have RESTful services as well
    • how much revenue comes in via web services?
      • 70%
      • only 30% comes through web site itself
      • big point here–allowing people to write third-party apps that interface with your “web site” will open up access/revenue
  • twitter
    • twitter.com only accounts for about 15% of traffic
    • 85% of traffic coming through APIs
  • programmableweb.com
    • list of APIs for major web properties
    • important to allow people to access the model without dealing with the view
    • more and more, SOAP-based APIs are going away
  • It’s all about the data
    • don’t bound up the data in a proprietary silo
    • view/web site is really just an implementation detail
  • web services
    • knee-jerk reaction is still to think about SOAP
    • SOAP is one implementation of web services
      • wasn’t even the first–had XML-RPC
      • many successors (RSS, ATOM, REST, etc.)
      • technologies have a lifecycle and SOAP is on the decline–been around for 10 years
    • Dave Winer, creator of SOAP, said in an interview on ITConversations that SOAP is a failure
      • “how long are we supposed to wait for the magic of soap to happen?”
      • “With SOAP we tried really hard to create a level playing field for small developers and large developers”
      • wanted SOAP to fade into the woodwork and just be how things are done, but never happened
    • amazon.com has both SOAP and REST
      • REST accounts for 85% of the web service calls
      • democracy in action–developers can choose either and they choose REST
    • simpler technologies win over time–XML over HTTP much simpler than SOAP
    • 12/06 — google officially deprecated their SOAP API
  • the ui is important, but don’t ignore the value of the raw data
  • question: with REST how do you handle authentication?
    • it’s all HTTP with REST so you handle it the same way you would with any other HTTP resource
    • SOAP was supposed to be protocol agnostic, but everyone uses HTTP so this is kind of pointless
      • only real example is using SOAP over JMS since it’s asynchronous, also guarantees delivery
      • but here again, if the web service will never be used on anything OTHER than JMS, why use SOAP instead of straight JMS?
  • REST is …
    • REpresentational State Transfer
    • SOAP used to be “Simple Object Access Protocol”
      • acronym has been deprecated–“no longer simple”
    • Roy Fielding coined REST term in doctoral dissertation (2000)
    • SOAP is a specification
      • one implementation of a service-oriented architecture
      • RPC, verb-oriented
      • not really dealing with objects but actions taken on data
    • REST is a set of architectural principles
      • resource-oriented, noun-oriented — object oriented
      • payload could be in XML, JSON, etc.–format of payload doesn’t matter
    • wikipedia has a great comparison between SOAP and REST
    • HTTP already has the right verbs available for CRUD
      • get, post, put, delete
      • REST is the SQL of the internet
      • URIs are unique identifiers for resources on the web
  • GETful Grails
    • lots of REST APIs only support get
    • important thing is to make sure you only expose idempotent requests via get
      • idempotent — repeat calls can’t change state of data on server
    • get requests get cached, bookmarked, etc.
      • e.g. using google maps–can pick a point on the map, set zoom level, etc. and email a link that contains the exact state of the map as a get request
    • can render objects as XML or JSON easily
      • render Airport.list() as XML
      • render Airport.list() as JSON
      • can also easily customize XML with Groovy Markup Builder
  • Content negotiation and the HTTP header
    • MIME types used to uniquely identify data types in internet calls
    • curl very handy tool for working with REST APIs
    • if you grab xml and output to a file, can use tidy to cleanup/indent the xml
    • accept header by default is */*
      • if want to get back resources in different formats, URI stays the same, but the return type could be text, html, xml, mp3, whatever
    • in conf/Config.groovy file can specify whether or not to pay attention to accept header passed by client
      • can also specify mime types
      • rather common to specify format type in URI (e.g. twitter.com/search.atom returns atom)
      • withFormat block used in controller to correspond to data types specified as action.format in url
        • e.g. list.xml would return whatever is specified in the withFormat/xml block in the controller
  • RESTful Grails
    • URI remains the same for resources
    • in Grails, can map closures to various HTTP verbs as actions
      • e.g. action = [POST:’create’, GET:’retrieve’, PUT:’update’, DELETE:’delete’]
      • this is still an XML-RPC approach since we’re still customizing things and saying “they’re asking for this, but this is what they really want”
    • can also hijack the index method and switch based on the request type
      • switch (request.method) and then have cases for each request type
    • can specify the allowed methods by action
      • static allowedMethods = [delete:’POST’, save:’POST’]
    • goal is to keep uri identical but vary the verb
    • can post XML and still use params as long as the xml node names match the domain class property names
    • good practice to get into is to always include the response.status code in the response
      • 200 for succesful get, 201 for successful create, etc.
      • also common to send back a representation of the created resource in 201 responses
    • if you have to post custom XML, have to go line-by-line and map nodes and attributes from XML to the domain class properties
      • e.g. airport.iata = request.XML.@iata
    • check out Castor — like Hibernate for XML
      • can set up mapping files to map between XML and POGOs
  • Summary
    • ui is important, but it’s the raw data that’s important
    • owe it to our constituency not to wrap data in a proprietary UI
      • future-proofs the application
    • nothing wrong with SOA and SOAP, but make sure this is what you really need
      • SOAP is on its way out–downside of adoption curve
      • REST is the way things are done today

Session Notes – Grails Quick Start

Presenter: Dave Klein – Author of Grails Quick-Start Guide (Pragmatic Programmers)
http://gquick.blogspot.com
http://twitter.com/daveklein

  • groovymag – 20% off with code 2gx1
  • Sample App – Java UG Mgmt App
    • Domain model:
      • Speaker
      • Meeting
      • Sponsor
      • Member (member data already in legacy db)
  • Groovy properties
    • by declaring, they automatically have get/set methods generated
    • can override these if you need to implement something specific in get/set
    • when you access properties via dot notation, behind the scenes it’s calling get/set
  • constraints
    • these determine the order in which things are listed in the list and form views
    • by default string fields get 255 varchar in the database
    • if you use a maxSize in the constraints this gives you a textarea on the edit page and a larger text data type in the db
  • toString method
    • by default this will be the class name and the ID
    • good idea to override so toString calls output something more useful
    • particularly helpful with drop-down lists since grails calls toString() on domain classes when generating drop-downs
  • custom validators
    • use groovy code to implement your own validation
    • can be inline in the constraints block or can be a separate closure
    • def meetingTimeValidator { val, obj ->
      def gc = new GregorianCalendar()
      gc.time = val
      gc.get(Calendar.HOUR) == 18 } // ensures meeting time is at 6 pm
  • unit tests
    • mockDomain() — allows to test domain classes in an isolated manner
      • e.g. mockDomain(Meeting, []) — this gives you an empty list and will be what’s accessed in your unit tests
      • this also gives you all the dynamic methods (GORM, validate(), etc.) in your mocked domain
    • remember that stubbed out tests will pass even though you haven’t implemented them, so you’ll see passing tests when you run your tests even though they aren’t doing anything
    • unit tests run quite a bit faster than integration tests
  • using a “real” db
    • just drop JAR for db drivers in lib directory and set the JDBC URL
    • dev, test, and production environments in DataSource config file
    • for production recommend using JNDI so you don’t have to store user name and password in the config file
  • mapping to existing data
    • e.g. member table–id field is member_num; Grails by default uses “id” as the id field name
    • other fields change to all lowercase and add underscores between words, e.g. firstName becomes first_name
    • table names by default are domain name singular (e.g. member not members)
    • if all this doesn’t match up, need to add a mapping block to the domain class
      • in case of Member class, id and email fields aren’t named correctly, and the table name is plural
    • static mapping = {
      table ‘members’
      version false // grails adds this to all your tables; used for optimistic concurrency
      id column: ‘member_num’
      columns {
      email column: ’email_address’
      }
      }
    • can use existing Hibernate XML mapping files instead of using DSL for mapping on a class-by-class basis
    • in this case a new field was added to an existing table; grails updated the schema but didn’t alter the existing fields in the table
    • basically will always add new fields and will make any other changes based on constraints if the changes are non-destructive
      • e.g. won’t shorten the length of an existing field
  • init block in Bootstrap
    • great place to stick test data–generate data so it’s available when the app fires up when you’re using the in-memory dev db
    • can check environments in bootstrapper so it will do specific things based on the environment the app is running in
    • new in Grails 1.2 is failOnError in save method
  • generate-all command
    • can do grails generate-all “*” to generate controllers, views, and tests for all domain classes
  • grails 1.2 uses tomcat instead of jetty for servlet container
    • also in 1.2 much of what was previously built in is now plugins–1.2 start page shows installed plugins
  • using multiple datasources in a grails app
    • a bit messy–lose a lot of the GORM methods on anything other than the primary datasource
  • can combine create forms across domain classes
    • e.g. in the meeting form, can add the fields to create the speaker on the fly
    • refer to other domain class (speaker in this case) using dot notation:
      <g:textField name=”speaker.firstName” value=”${meetingInstance?.speaker?.firstName}” />
  • save methods in controllers
    • params is a map containing all the fields from the submitted page
    • params will map directly to domain classes in constructors
      • e.g. def meeting = new Meeting(params)
        • maps all the params by name to the Meeting domain class properties
        • if you have nested classes, e.g. speaker, sponsor, maps those as well
      • you do need to save the objects in order for the final save to work correctly
    • if you want to manually flush the hibernate session pass flush:true to the save method
    • flash scope used for storing data for the current request and the request immediately following
      • easier than using session and having to clear it out later
    • validation happens automatically when save() is called, but you can call it explicitly as well
    • controller actions are transactional by default, but you can control this explicitly as well
  • services
    • these are spring beans
    • autowired by name
      • to use, def myController
    • can inject into controllers, domain classes, taglibs
    • help keep controllers cleaner and leaner
    • not the right place for the domain logic (avoid anemic domain syndrome)
    • can create manually or use grails create-service
    • generation script by default sets all service methods to be transactional
      • if one service method calls another, it will be transactional
    • PersonService used in conjunction with Member, but there’s no person class
      • works because in Groovy, don’t need to use inheritance — all by behavior
  • plugins
    • over 300 plugins available
    • 47 javascript plugins
    • 21 security plugins
    • 36 css plugins
    • easy to install — grails install-plugin pluginName
    • http://grails.org/plugin/home
  • grails ui plugin — based on YUI library
    • provides
      • DataTable
      • Dialog
      • Auto-Complete
      • Accordian control
      • more
    • e.g. better date picker than default drop-downs used for selecting dates
      • just replace g:datePicker with gui:datePicker in gsp pages
      • declare the tablib and the specific resources being used on each page
        • this way it only loads what you need
      • this returns the date to the controller as a string, so have to modify the controller a bit
        • params.dateTime = new Date().parse(“MM/dd/yyyy hh:mm”, params.dateTime)
        • default grails datepicker does this step automatically
  • url mapping
    • create more meaningful urls
    • help to hide implementation details
    • gateway to REST in grails
    • e.g. find meeting by year and month
    • update show action to support new url mapping
      • def show = {
        def meetingInstance
        if (params.year) {
        meetingInstance = findMeetingByMonthAndYear(params)
        } else {
        meetingInstances = Meeting.get(params.id)
        }
        }
  • gsp tags
    • build reusable components
    • get code out of the view
    • make pages more readable/maintainable
    • encapsulate domain knowledge
    • very easy to create

SpringOne2GX – Day 1 Keynote

Brain dump of the SpringOne2GX day 1 keynote featuring Rod Johnson, Graeme Rocher, and others.

  • Major tenets of SpringSource
    • simplification
    • community
    • innovation
  • simplification
    • amount of code in Spring apps has decreased over time as the amount of code in Spring itself has increased
    • framework does more so you do less
    • nice chart showing number of lines of code in Spring sample apps over time
  • community
    • large–Gartner estimates at about 3 million developers
    • traits of community: passionate, highly skilled, think for themselves
    • get involved!
      • ask/answer questions on mailing list and forums
      • submit features and bugs to JIRA
      • participate in events (UGs, meetups, etc.)
      • start a UG or meetup in your area if there isn’t one
      • contribute code
        • doesn’t necessarily have to be core code–extensions, tests, plugins, etc.
  • innovation
    • everything can be improved
    • always new challenges to overcome

Spring 3.0

  • simplify configuration
  • MVC improvements
  • REST support built in
  • support for JSR-330 (DI via annotations)
  • Spring Integration — demo
    • concept: “have Spring all the way down in your stack”

Groovy/Grails

  • all about productivity
  • integration all done for you
  • more prescriptive
    • while Spring is about choice, that means more configuration
    • Grails takes away some choice, but the trade-off is increased productivity
  • Groovy/Grails state of the nation
    • huge growth in recent months–150% increase in traffic to web sites
    • Groovy 1.7 and Grails 1.2 released coming soon
    • big performance improvements in Grails 1.2
    • plugin ecosystem very healthy
      • 25 million lines of user contributed code in 300+ plugins
      • cool stuff going on with alternative persistence mechanisms (e.g. CouchDB), RIAs, etc.
      • iPhone ads: “there’s an app for that” — Grails: “there’s a plugin for that”
    • Challenges
      • IDE support–gets much better with newest SpringSource Tool Suite (STS)
      • hosting/cloud — need better support, easier deployment

Lifecycle and Tools

  • Build -> Run -> Deploy
  • tc Server developer edition — free download
    • really nice dashboard with performance and health insight
  • Spring Insight Dashboard demo
    • real-time performance graph
    • huge amount of detail you can drill into by clicking on a request
    • links back to STS–takes you right to the relevant spot in the code
    • app health screen tracks performance by component over time
      • uses 99th percentile so you’re focused on what most users are experiencing
  • SpringSource Tool Suite
    • Eclipse based
    • single download for everything, including tc server

Keys to Future

  • developers
  • simplification
  • innovation
  • community
  • SpringSource + VMWare
    • VMWare committed to community and open source
    • VMWare serious about middleware