text:
Build a RESTful Web service
An introduction to REST and the Restlet framework
Before you start
About this tutorial
REST is a way of thinking, not a protocol or standard. It's a style of designing loosely coupled applications — more often than not, applications oriented for the Web — that rely on named resources rather than messages. In this tutorial, you'll get to know what REST is and how to build RESTful applications with Restlets, a lightweight REST framework for Java™ applications.
This tutorial guides you step-by-step through the fundamental concepts of REST and building applications with Restlets. You'll learn how to:
- Define RESTful Web services
- Implement them with the Restlet framework
- Verify them with the JUnit testing framework
When you are done with the tutorial, you will understand the benefits of designing with RESTful principles, and you'll see how the Restlet framework makes it easy.
To get the most from this tutorial, you should be familiar with Java syntax and the basic concepts of object-oriented development on the Java platform. You should also be familiar with Web applications. Familiarity with Groovy, JUnit, DbUnit, and XMLUnit is also helpful.
System requirements
To follow along and try out the code for this tutorial, you need a working installation of either:
- Sun's JDK 1.5.0_09 (or later)
- IBM Developer Kit for Java technology 1.5.0 SR3
- Apache Ant 1.7 or greater
There are two versions of the source code for this tutorial (see Download). One version includes all code and required dependencies (the Restlet framework, JUnit, XMLUnit, and DbUnit). Readers with a low-bandwidth connection might prefer to download the Restlet framework, JUnit, XMLUnit, and DbUnit from their respective sites (see Related topics) and use the Download package version that does not include dependencies.
The recommended system configuration for this tutorial is:
- A system supporting either the Sun JDK 1.5.0_09 (or later) or the IBM JDK 1.5.0 SR3 with at least 500MB of main memory
- At least 20MB of disk space to install the software components and examples covered
The instructions and examples in the tutorial are based on a Microsoft® Windows® operating system. All the tools covered in the tutorial also work on Linux® and UNIX® systems.
What is REST?
REST is a style of designing loosely coupled Web applications that rely on named resources — in the form of Uniform Resource Locators (URLs), Uniform Resource Identifiers (URIs), and Uniform Resource Names (URNs), for instance — rather than messages. Ingeniously, REST piggybacks on the already validated and successful infrastructure of the Web — HTTP. That is, REST leverages aspects of the HTTP protocol such as
GET and
POST requests. These requests map quite nicely to standard business-application needs such as create read, update, and delete (CRUD), as shown in Table 1:
Table 1. CRUD/HTTP mapping
|Application task
|HTTP command
By associating requests, which act like verbs, with resources, which act like nouns, you end up with a logical expression of behavior —
GET this document and
DELETE that record, for example.
Roy Fielding, the veritable father of REST, states in his PhD dissertation that REST "emphasizes scalability of component interactions, generality of interfaces, independent deployment of components, and intermediary components to reduce interaction latency, enforce security, and encapsulate legacy systems" (see Related topics). Building RESTful systems isn't difficult, and the systems are highly scalable while also being loosely coupled to the underlying data; they also leverage caching quite nicely.
Everything on the Web (pages, images, and so on) is in essence a resource. REST's reliance on named resources rather than messages facilitates loose coupling in application design, because it limits the exposure of the underlying technology. For instance, the following URL exposes a resource without implying anything about the underlying technology: http://thediscoblog.com/2008/03/20/unambiguously-analyzing-metrics/
This URL represents a resource — an article called "Unambiguously analyzing metrics." A request for this resource leverages the HTTP
GET command. Notice that the URL is noun-based. A verb-based version (which might look something like http://thediscoblog.com/2008/03/20/getArticle?name=unambiguously-analyzing-metrics) would violate REST principles, because it embeds a message, in the form of getArticle. You could also imagine posting a new resource (say, an article resource such as http://thediscoblog.com/2008/03/22/rest-is-good-for-you/) via HTTP's
POST command. Although you can also imagine associated, verb-based APIs — such as createArticle?name=rest-is-good-for-you and deleteArticle?name=rest-is-good-for-you — such calls hijack the HTTP
GET command and, for the most part, ignore the already available (and successful) HTTP infrastructure. In other words, they are not RESTful.
The beauty of REST is that resources can be anything, and how they are represented can vary too. In the preceding example, the resource is an HTML file; accordingly, the format of the response would be HTML. But the resource could have easily been an XML document, serialized object, or JSON representation. It really doesn't matter. What matters is that a resource is named and that communication with it doesn't affect its state. Not affecting state is important because stateless interactions facilitate scalability.
Why should you care?
To quote Leonardo da Vinci, "simplicity is the ultimate sophistication." The implementation of the World Wide Web is as simple as it gets and an undeniable success. REST leverages the Web's simplicity and thus yields highly scalable, loosely coupled systems that, as it turns out, are simple to build.
As you'll see, the hardest part of building a RESTful application is deciding on the resources you want to expose. Once you've done that, using the Restlet framework makes building RESTful Web services a snap.
Off to the races: Building a RESTful API
In this section, you'll build a RESTful API for a Web service that leverages the functionality of an existing database-backed application.
RESTful races
Imagine an online application that manages races in which contestants run various distances (such as the Chicago Marathon). The application manages races (or events) and the runners associated with them. And it reports a particular runner's time (how long it took to run the race) and rank (what place the runner finished in). The race-management company, Acme Racing, wants you to build a RESTful Web service that enables sponsors to create new races and racers for a particular race, and that can provide official results for a particular race.
Acme Racing already has a legacy fat-client application that supports similar requirements and leverages a simple database along with a domain model. Thus, the job of exposing this functionality is all that's left to do. Remember that the beauty of REST is its implicit loose coupling with an underlying application. Accordingly, your job, at the moment, isn't to worry about the data model or the technology associated with it — it's to construct a RESTful API that supports the company's requirements.
Race URIs
Acme Races would like sponsors to be able to:
- View the details of existing races
- Create new races
- Update existing races
- Delete races
Because REST boils down to named resources, the API becomes a series of URI patterns, and the behavior associated with a resource is invoked via standard HTTP commands.
As you can see, the client's requirements map nicely to CRUD. And as you know from Table 1, REST supports CRUD via the HTTP
PUT, and
DELETE requests, respectively. Accordingly, a base RESTful URI that supports these requirements could be http://racing.acme.com/race. Note that in this case, race is the resource clients would work with.
Invoking this URI with an HTTP
GET would return a list of races. (Don't worry about the format of the response just yet.) To add a new race, you would invoke the same URI with an HTTP
POST containing the appropriate information (for instance, an XML document containing required race information, such as name, date, and distance).
For updating and deleting existing races, you would need to act on a particular
instance of a race. Accordingly, individual races can be addressed with a URI of
http://racing.acme.com/race/race_id. In this case,
race_id represents a placeholder for any race identifier (such as 1 or 600meter). Consequently, viewing an existing race instance would be an HTTP
GET to that URI; updating or deleting a race would be a
PUT or
DELETE request, respectively.
Acme Racing also wishes to expose data regarding runners associated with a race. They'd like their service to support:
- Obtaining all runners for a particular race. This data should also include run times and ranks for a race that's already completed.
- Creating one or more runners for a particular race.
- Updating a runner's information (such as age) for a particular race.
- Deleting a runner for a particular race.
Acme would also like the service to let users view individual data for a particular runner in a particular race.
Just as with races, applying RESTful URIs to runners associated with a race is a logical exercise. Viewing all runners for a particular race, for example, would be implemented via a
GET request to http://racing.acme.com/race/race_id/runner.
Obtaining individual data for a runner in a race would be addressed as http://racing.acme.com/race/race_id/runner/runner_id.
Just like race_id, runner_id is a placeholder for the logical implementation of IDs, which could be numbers, names, alphanumeric combinations, and so on.
Adding runners to a race would be a
POST request to http://racing.acme.com/race/race_id/runner. Updating or deleting particular runners would be, respectively,
PUT and
DELETE requests to http://racing.acme.com/race/race_id/runner/runner_id.
Thus, these URIs (each supporting some or all of the four standard HTTP requests) capture Acme Racing's requirements:
- /race
- /race/race_id
- /race/race_id/runner
- /race/race_id/runner/runner_id
Remember, a particular URI can map to more than one HTTP verb (for instance, applying an
GET to /race returns data; applying a
POST with appropriate data creates data on the server). Accordingly, some HTTP commands wouldn't be implemented. For example, /race wouldn't support the
DELETE command (Acme Racing wouldn't want to delete all races); /race/race_id could support the
DELETE command because removing a particular instance of a race is a business requirement.
Formating the resource
In this section, you'll construct a series of XML documents to represent the resources that the RESTful races Web service will support.
Race URIs
The RESTful API you built in the preceding section for Acme Racing covers the network endpoints or URIs but not the resources. As far as REST is concerned, the format of the resources doesn't matter, as I mentioned earlier. You could pass XML or binary streams back and forth, for example.
XML is arguably the lingua franca of machine-to-machine communication in the context of business transactions, so it makes sense to construct a series of XML documents that the RESTful service will support. The domain for racing is fairly simple, and you can use an existing data model, so the task of defining a few XML documents that represent races and runners is straightforward.
For instance, a race can be defined in XML as in Listing 1:
Listing 1. XML document for a race
<race name="Mclean 1/2 Marathon" date="2008-05-12" distance="13.1" id="1"> <uri>/races/1</uri> <description/> </race>
Note that a
<race> has an
id and that Listing 1 includes a URI as part of the definition of a race. This is a key aspect of REST and indeed, the Web — resources are related and should be linked together. Accordingly, a
<race> always contains a
<uri> element describing its RESTful representation. The XML in Listing 1 is arguably the response of a
GET request to /races/1.
To create a new race, you could omit the
id aspect (because managing unique IDs is something the application you're building here controls). This implies you could exclude the
<uri> element as well. Consequently, a
POST request would look something like Listing 2:
Listing 2. Race-creation XML
<race name="Limerick 2008 Half" date="2008-05-12" distance="13.4"> <description>erin go braugh and have a good time!</description> </race>
What about runners? A runner is connected to race, right? So the
<race> element supports holding one or more
<runner> elements, as shown in Listing 3:
Listing 3. Runners associated with a race
<race name="Limerick 200 Half" date="2008-05-12" distance="13.4" id="9"> <uri>races/9</uri> <description>erin go braugh and have a good time!</description> <runners> <runner first_name="Linda" last_name="Smith" age="25" id="21"> <uri>/races/9/runner/21</uri> </runner> <runner first_name="Andrew" last_name="Glover" age="22" id="20"> <uri>/races/9/runner/20</uri> </runner> </runners> </race>
The XML document in Listing 3, for example, is what would be returned via the URI /race/race_id/runner. The API also supports CRUD operations performed on a single runner via the URI /race/race_id/runner/runner_id.
Accordingly, the XML for these CRUD actions looks like Listing 4:
Listing 4. CRUD XML
<race name="Mclean 1/2 Marathon" date="2008-05-12" distance="13.1" id="1"> <uri>/races1</uri> <description /> <runner first_name="Andrew" last_name="Glover" age="32" id="1"> <uri>/races/1/runner/1</uri> <result time="100.04" place="45" /> </runner> </race>
Note that if the race is already complete, a runner's results can be included in the XML document. Remember, using a
POST request means creating a runner; consequently, the
<runner> element's
id attribute would not be present.
You've defined a RESTful API that maps quite nicely to CRUDing races and runners. And you've defined the format of the communication: XML documents. In this section, you'll start to put this all together using an innovative framework that is modeled after servlets.
The Restlet framework
Restlet applications are akin to servlet applications in that they reside in a container, but in practice they are quite different in two major ways. First, Restlets use no direct notion of HTTP or its stateful manifestations such as cookies or sessions, per se. Second, the Restlet framework is extremely lightweight. As you'll see, a fully functional RESTful application can be built with a handful of classes that extend from a few core Restlet base classes. Configuration and deployment leverage existing container models, so you simply update the customary web.xml file and deploy a standard Web archive (WAR) file.
For the most part, the bulk of a RESTful application built with the Restlet framework
requires the use of two base classes:
Application and
Resource. Logically speaking, an
Application instance maps URIs to
Resource instances.
Resource instances do the work of handling the basic CRUD commands, which are, of course, mapped to
PUT, and
The race application
You create a starting point with the Restlet framework by extending from the framework's
Application class. In this class, you define
Resources that respond to URIs. This definition process is done with the framework's
Router class. For example, if you have a URI such as order/order_id, you need to specify which object can handle these requests. This object is an instance of the framework's
Resource type. You link objects with URIs by attaching them to a
Router instance, as in Listing 5:
Listing 5. Creating
Router instances and mapping URIs
Router router = new Router(this.getContext()); router.attach("order/{order_id}", Order.class);
So in this example, the URI order/order_id is logically mapped to an
Order class (which, in turn, extends
Acme Racing has the four logical RESTful URIs that you've already defined — four patterns that work with various aspects of races and runners:
- /race
- /race/race_id
- /race/race_id/runner
- /race/race_id/runner/runner_id
The behavior of each URI (such as if it works with
GET, and so on) isn't important at this point. The behavior of each
Resource is the job of a
Resource instance; however, the
Application instance is used to map these URIs to (yet-to-be-defined)
Resources via a
Router instance, as shown in Listing 6:
Listing 6. Mapping Acme Racing's URIs to
public class RaceApplication extends Application{ public RaceApplication(Context context) { super(context); } public Restlet createRoot() { Router router = new Router(this.getContext()); router.attach("/race", RacesResource.class); router.attach("/race/{race_id}", RaceResource.class); router.attach("/race/{race_id}/runner", RaceRunnersResource.class); router.attach("/race/{race_id}/runner/{runner_id}", RaceRunnerResource.class); return router; } }
The base class,
Application, is an abstract class. Extending classes must implement the
createRoot() method. In this method, you can create a
Router instance and attach
Resources to URIs as I've done in Listing 6.
As you can see, there are four different
Resource classes. I've
named them to match the desired high-level behavior of the URI. For instance, the /race URI is intended to work with multiple race instances; consequently the
Resource type is named
RacesResource. Once an
id is included in the URI (/race/race_id), the implication is that a single race is being manipulated; accordingly, the
Resource type is apply named
Race resources
Now that you've defined the
Application instance to handle four different URI patterns, you must implement the four
Resource types in the Restlet framework are known as Restlets. They are the heart of any RESTful application developed with the Restlet framework. Unlike the
Application type, the base
Resource class is not abstract. It's more like a template with default behavior that you can override as needed.
At a high level,
Resource has four methods that require
overriding. Not coincidentally, they map to the basic HTTP commands that are the touchstone of REST —
PUT, and
DELETE. Because the
Resource class is nonabstract, the framework requires a paired method to be implemented for desired behavior to be invoked. For instance, if you want a particular resource to respond to
DELETE requests, you would first implement the
delete() method. Second, you also must implement the
allowDelete() method and have this method return
true (it defaults to
false). By default, the corresponding
POST, and
DELETE allow methods return
false, and the
allowGet() method returns
true. This means for read-only
Resources, you need to override only one method (instead of two in the other three cases). You can alternatively call the
setModifcation(true) in a
Resource class and thus not have to override individual HTTP verb
allow methods.
For instance, the
RacesResource is intended to respond to
GET requests with an XML document that describes the races in the system. Users can also create new races via this
Resource type. Therefore, the
RacesResource class overrides at least three methods from the
Resource base class:
Resources instances, by default, are read-only. Hence
allowGet() method doesn't need to be overridden.
Generating XML documents
In Formatting the resource, we decided to leverage XML as
the data mechanism for sharing information between clients and the service. Your
Restlets, therefore, must manipulate XML: build it in the case of a
GET and consume it in the case of a
PUT, or
DELETE. In this section, you'll take the pain out of generating and manipulating XML documents by leveraging the Groovy scripting language (see Related topics).
Leveraging Groovy
Working with XML is no easy chore. It can be tedious and error prone, to say the least. Fortunately, Groovy makes working with XML much easier.
You'll leverage Groovy's power to generate XML and do the tedious job of manipulating XML documents. Working with XML in Groovy couldn't be any easier. For instance, parsing an XML document is a cakewalk. Take the XML document in Listing 7:
Listing 7. A simple XML document to parse
<acme-races> <race name="Alaska 200 below" date="Thu Jan 01" distance="3.2" id="20"> <uri>/races/20</uri> <description>Enjoy the cold!</description> </race> </acme-races>
Suppose you wanted to grab the value of the
<race> element's
name attribute. All you need to do is pass in an instance of the XML document to Groovy's
XMLSlurper class, call the
parse() method, and then navigate to your desired element or attribute, as shown in Listing 8:
Listing 8. Parsing XML in Groovy
def root = new XmlSlurper().parseText(raceXML) def name = root.race.@name.text()
If you want the description, it's as easy as calling
Creating XML is easy too. If you wanted to create the XML snippet in Listing 7, all you have to do is create an instance of Groovy's
MarkupBuilder class and add nodes to it, as in Listing 9:
Listing 9. Creating XML couldn't be easier
def writer = new StringWriter() def builder = new MarkupBuilder(writer) builder."acme-races"() { race(name: "Alaska 200 below", date: "Thu Jan 01", distance: "3.2", id: "20") { uri("/races/20") description("Enjoy the cold!") } } println writer.toString()
Note how elements are added to the XML document by attaching names to the
builder instance. I had to put quotation marks around
acme-races because hyphens aren't allowed in string literals in Groovy; consequently, making
acme-races a
String solves that problem nicely.
Elements can have attributes. Attribute names and values are created by constructing a Groovy map, which links the two together (for example,
name:"Alaska 200 below").
The data layer
This section describes the existing domain objects that make the up data layer that your RESTful service will reuse.
Domain objects
As you know from Off to the races: Building a RESTful API, Acme Racing invested in a data layer for a previous project and wants to reuse it for the new Web service. This, of course, makes your job even easier. In a nutshell, the data layer consists of three business objects:
Runner, and
Result. They are effectively managed by Spring and Hibernate; however, these frameworks are hidden from you; you simply have a JAR file that works nicely (that is, lets you easily create new races, find existing runners, and so on).
The business objects support a series of finder methods that make obtaining race and runner instances quite easy. Objects can be persisted, updated, and removed from the underlying database via
update(), and
remove() methods, respectively.
For example, a
Race object supports a series of finder methods and facilitates manipulating persisted data nicely. The
Race object's API is straightforward, as shown in Listing 10:
Listing 10.
Race's API
Collection<Race> findAll(); Race findById(long id); Race findByName(String name); void create(Race race); void update(Race race); void remove(Race race);
Race instance has a number of properties, as shown in Listing 11:
Listing 11.
Race's properties
private long id; private String name; private Date date; private double distance; private Set<Runner> participants; private Set<Result> results; private String description;
All of
Race's properties are available via getters and setters. What's more, collections of items (such as
participants and
results) support adding individual items. Therefore, the
Race object has an
addParticipant() method, shown in Listing 12:
Listing 12.
addParticipant() method
public void addParticipant(final Runner participant) ;
As you've seen, working with this domain model is quite easy.
Building and testing the service
Now that you know how you'll work with XML and already have a data layer to use, it's time to continue building your RESTful application with Restlets and do some test preparation.
The Races service
Recall that Acme Racing would like its service to enable clients to view existing races as well as create new ones. You've already outlined the RESTful URI that'll support this behavior: /race.
Via the
Router class in the
RaceApplication class, you linked this URI to the
RacesResource class. You already know that you must implement three methods:
Accordingly, create a class called
RacesResource and ensure
that it extends
org.restlet.resource.Resource. Also, implement a three-parameter constructor, as shown in Listing 13:
Listing 13. Three-parameter constructor in
public class RacesResource extends Resource { public RacesResource(Context context, Request request, Response response) { super(context, request, response); } }
Restlets must be instructed how to communicate resource representations properly. Because XML will serve as the resources format, you must direct your Restlet by adding an XML variant type.
Variants, in Restlets, represent a format for
Resources. The base class,
Resource, contains a
getVariants() method that facilitates adding various
Variant types. Accordingly, add the line in Listing 14 to your constructor:
Listing 14. Signifying XML as a variant
this.getVariants().add(new Variant(MediaType.TEXT_XML));
The Restlet framework supports a wide variety of media types, including images and video.
GET requests
Now it's time to implement the easiest behavior of the class: handling a
GET request. Override the
getRepresentation() method as shown in Listing 15:
Listing 15. Overriding
public Representation getRepresentation(Variant variant) { return null; }
As you can see, this method returns a
Representation type, of which there are multiple implementations. One implementation — aptly dubbed
StringRepresentation — represents strings and will suffice for your needs.
As you know, you already have a legacy domain model that supports working with the database. It also turns out that someone has already written a utility class, called
RaceReporter, that transforms domain objects into XML documents. This class's
racesToXml() method takes a collection of
Race instances and returns a
String representing an XML document looking something like Listing 16:
Listing 16. An XML response
<acme-races> <races> <race name="Leesburg 5K" date="2008-05-12" distance="3.1" id="5"> <uri>/races/5</uri> <description/> </race> <race name="Leesburg 10K" date="2008-07-30" distance="6.2" id="6"> <uri>/races/6</uri> <description/> </race> </races> </acme-races>
In fact, this XML document is an example of what your RESTful Web service will return when the /race URI is invoked with a
GET request.
Therefore, your job is to link the retrieval of all race instances in the underlying data store; in fact, at this point, you can already write a test.
Testing the service
Using the Restlet framework, you can construct a client instance and have it invoke your RESTful Web service. Moreover, you can leverage XMLUnit (see Related topics) to verify that the service's output is some known XML document. Last, but not least, you can also use DbUnit (see Related topics) to put the underlying database into a known state (so you can always get back the same XML document).
Using JUnit 4, you can create two fixtures that properly initialize XMLUnit and DbUnit, as shown in Listing 17:
Listing 17. Setting up XMLUnit and DbUnit
@Before public void setUpXMLUnit() { XMLUnit.setControlParser( "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"); XMLUnit.setTestParser( "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"); XMLUnit.setSAXParserFactory( "org.apache.xerces.jaxp.SAXParserFactoryImpl"); XMLUnit.setIgnoreWhitespace(true); } @Before public void setUpDbUnit() throws Exception { Class.forName("org.hsqldb.jdbcDriver"); IDatabaseConnection conn = new DatabaseConnection( getConnection("jdbc:hsqldb:hsql://127.0.0.1", "sa", "")); IDataSet data = new FlatXmlDataSet(new File("etc/database/race-db.xml")); try { DatabaseOperation.CLEAN_INSERT.execute(conn, data); } finally { conn.close(); } }
In the
setUpDbUnit method, an XML representation of the database is inserted into the database via the
CLEAN_INSERT command. This XML file effectively inserts six different races. Therefore, the response to a
GET will be an XML document with six races.
Next, you can create a test case that invokes an HTTP
GET on the /race URI, obtains the response XML, and compares it to a control XML file using XMLUnit's
Diff class, as demonstrated in Listing 18:
Listing 18. Verifying a
GET response with XMLUnit
@Test public void getRaces() throws Exception { Client client = new Client(Protocol.HTTP); Response response = client.get("http://localhost:8080/racerrest/race/"); Diff diff = new Diff(new FileReader( new File("./etc/control-xml/control-web-races.xml")), new StringReader(response.getEntity().getText())); assertTrue(diff.toString(), diff.identical()); }
The control-web-races.xml file is the expected XML response from the Web service. It contains the data shown in Listing 19:
Listing 19. A control XML file
<acme-races> <races> <race name="Mclean 1/2 Marathon" date="2008-05-12" distance="13.1" id="1"> <uri>http://localhost:8080/races/1</uri> <description/> </race> <race name="Reston 5K" date="2008-09-13" distance="3.1" id="2"> <uri>http://localhost:8080/races/2</uri> <description/> </race> <race name="Herndon 10K" date="2008-10-22" distance="6.2" id="3"> <uri>http://localhost:8080/races/3</uri> <description/> </race> <race name="Leesburg 1/2 Marathon" date="2008-01-02" distance="13.1" id="4"> <uri>http://localhost:8080/races/4</uri> <description/> </race> <race name="Leesburg 5K" date="2008-05-12" distance="3.1" id="5"> <uri>http://localhost:8080/races/5</uri> <description/> </race> <race name="Leesburg 10K" date="2008-07-30" distance="6.2" id="6"> <uri>http://localhost:8080/races/6</uri> <description/> </race> </races> </acme-races>
Running this test now, of course, causes a series of failures, because you haven't implemented the RESTful service yet. Note too that the Ant build file included in the source download contains tasks for deploying a WAR file and starting and stopping Tomcat (see Download). These are prerequisites for running a successful test.
It turns out that fulfilling the
GET request is a cakewalk. All that's required is to invoke the
findAll method on the
Race domain object, then pass in the result of that call to
racesToXml() method. Accordingly, you need to update the
RacesResource instance with a new member variable along with a new initialization in the constructor, as shown in Listing 20:
Listing 20. Don't forget to add the
public class RacesResource extends Resource { private RaceReporter reporter; public RacesResource(Context context, Request request, Response response) { super(context, request, response); this.getVariants().add(new Variant(MediaType.TEXT_XML)); this.reporter = new RaceReporter(); } }
Now, it becomes quite easy to finish implementing the
GET request. Simply add three lines to the
getRepresentation method, as shown in Listing 21:
Listing 21. Finishing the
GET request
public Representation getRepresentation(Variant variant) { Collection<Race> races = Race.findAll(); String xml = this.reporter.racesToXml(races); return new StringRepresentation(xml); }
Believe it or not, that's it!
But wait: don't you have to deploy this application to test it?
Deployment and verification
Before you can actually test your RESTful service that returns a list of races, you need to deploy the application. This section shows you how.
Configuring web.xml
Luckily, deploying a Restlet application couldn't be any easier. You simply create a normal WAR file and ensure that the web.xml file is configured appropriately.
For a Restlet application to function properly in a servlet container, you must update the web.xml file to:
- Properly load your application
- Route all requires through the framework's custom servlet
Consequently, your web.xml file should look like Listing 22:
Listing 22. Sample web.xml file
<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>RESTful racing</display-name> <context-param> <param-name>org.restlet.application</param-name> <param-value>RaceApplication</param-value> </context-param> <servlet> <servlet-name>RestletServlet</servlet-name> <servlet-class>com.noelios.restlet.ext.servlet.ServerServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>RestletServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
As you can see, in the first part of Listing 22,
org.restlet.application is paired with the class name of the Restlet application, which is
RaceApplication. (You might need to fully qualify that name if you gave it a package name.) Note too that the last section of the document maps all requests to the
RestletServlet type, which was previously mapped to the
com.noelios.restlet.ext.servlet.ServerServlet class.
Testing RESTfully
Testing your RESTful Web service is now a matter of rerunning the test case in Listing 18.
Another look at the test starts to explain some things too. The Restlet's
Client object supports the basic HTTP commands of
POST, and
DELETE. And the
Client object can take the form of different protocols — you just happen to be relying on HTTP in this case.
GET request already works (see Figure 1), so you can write another test. This time, flesh out the desired behavior of a
POST; that is, test the creation of a new race via the
RacesResource class.
Figure 1. Viewing a RESTful GET request in a browser
To test a
POST, you need to fashion an XML request document with the relevant information and ensure that the service sends back a successful response. Of course, it turns out that writing this test is fairly simple. All you need to do is add some additional code to the existing JUnit class, as shown in Listing 23:
Listing 23. The
createRace test case
private static String raceXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<acme-races>\n" + " <race name='Limerick 2008 Half' date='2008-05-12' distance='13.4'>\n" + " <description>erin go brach</description>\n" + " </race>\n" + "</acme-races>"; @Test public void createRace() { Form form = new Form(); form.add("data", this.raceXML); Representation rep = form.getWebRepresentation(); Client client = new Client(Protocol.HTTP); Response response = client.post("http://localhost:8080/racerrest/race/", rep); assertTrue(response.getStatus().isSuccess());
As you can see, Listing 23 quickly fashions a
String that
represents an XML document. In this case, I'm creating a new race called the Limerick 2008 Half. Then it uses the Restlet framework's
Client object to post this document to the server. Finally, it ensures that a success indication is returned.
Now run the test. It fails, doesn't it? That's because you haven't implemented the
POST request code, which you'll do in the next section.
Race creation RESTfully
Creating races via the RESTful Web service is a matter of a few steps: receiving an XML document, parsing it, creating a new
Race instance in the underlying database, and finally returning a response indicating the result of the transaction. This section covers these steps.
POST requests
To implement a create style behavior via REST, you need to handle
POST requests logically. Accordingly, in the
RacesResource class, you must override two methods:
allowPost() and
post() method does all the work here. It takes a
Representation instance, from which you can obtain posted data. Recall that the
createRace test case in Listing 23 associated the XML document with a name:
data. Consequently, via the Restlet framework's
Form object, you can obtain a
String representing the incoming XML, which you can then pass to the provided
RaceConsumer object. This object is handy enough to accept XML documents and correspondingly manipulate the underlying database.
If the transaction works, you'll then respond accordingly with a successful response; otherwise, you'll need to respond with a failure message.
Go ahead and override
allowPost() and
post(), as shown in Listing 24:
Listing 24. Overriding
POST methods
public boolean allowPost() { return true; } public void post(Representation representation) {}
Because you'll use the
RaceConsumer object, it makes sense to add it as a member variable of the
RacesResource class and to initialize it in the constructor. Update your object accordingly, as shown in Listing 25:
Listing 25. Adding the
RaceConsumer class
public class RacesResource extends Resource { private RaceReporter reporter; private RaceConsumer consumer; public RacesResource(Context context, Request request, Response response) { super(context, request, response); this.getVariants().add(new Variant(MediaType.TEXT_XML)); this.reporter = new RaceReporter(); this.consumer = new RaceConsumer(); } }
Next, ensure your
post() method looks like Listing 26:
Listing 26. Implementing
public void post(Representation representation) { Form form = new Form(representation); String raceXML = form.getFirstValue("data"); Representation rep = null; try { long id = this.consumer.createRace(raceXML); getResponse().setStatus(Status.SUCCESS_CREATED); rep = new StringRepresentation(raceXML, MediaType.TEXT_XML); rep.setIdentifier(getRequest().getResourceRef().getIdentifier() + id); } catch (Throwable thr) { getResponse().setStatus(Status.SERVER_ERROR_INTERNAL); rep = new StringRepresentation("there was an error creating the race", MediaType.TEXT_PLAIN); } getResponse().setEntity(rep); }
As you can see, a lot is going on in the
post method; however, upon close inspection, things aren't as cerebral as they seem. First, the incoming XML is obtained via the
Form object. The XML (in the form of a
String) is then passed to the
createRace() method of the
consumer instance. If things worked (that is, the race was persisted), a response is generated that contains a successful status and then a rehashing of the incoming XML, plus the resulting URI (that is,
race/43, where 43 is the
id of the newly created race).
If things don't go well, the same process is essentially followed except that a failure status is returned with a failure message: no URI is returned because nothing was created.
Go ahead and rerun the
createRace test. Assuming you've redeployed the RESTful Web application, things should work quite nicely!
A point RESTed
This tutorial managed to implement only a modest number of Acme Racing's requirements. But in the process of doing so, you've seen that working with Restlets is quite simple. The hardest part of the whole exercise was figuring out the logical RESTful API. The source code for this tutorial has all features implemented for your learning pleasure (see Download).
The poet Alexander Pope said, "There is a certain majesty in simplicity which is far above all the quaintness of wit." This couldn't be more true when it comes to REST. Remember, REST is a way of thinking — a style of designing loosely coupled applications that rely on named resources rather than messages. And by piggybacking on the already validated and successful infrastructure of the Web, REST makes these applications simple to design and implement. And REST applications scale quite well.
This tutorial covered only a handful of the Restlet framework's features, but don't let that fool you. The framework does a lot, including adding security when you need it. Restlets are a joy to code, and the code base is easy understand once you see a few Restlets coded.
Albert Einstein said, "Everything should be made as simple as possible, but not simpler." I hope you agree with me that the Restlet framework and REST itself exemplify this mantra's wisdom.
Downloadable resources
- PDF of this content
- Sample code with dependent libraries (j-rest.zip | 19.5MB)
- Sample code without dependent libraries (j-rest2.zip | 19KB)
Related topics
- Architectural Styles and the Design of Network-based Software Architectures (Roy Thomas Fielding, University of California at Irvine, 2000): Fielding's doctoral dissertation describing REST.
- Restlet: Visit the Restlet framework Web site.
- "Fluently Groovy" (Andrew Glover, developerWorks, March 2008): Get started with Groovy. Learn about Groovy's syntax and productivity features, like native collections, built-in regular expressions, and closures. Write your first Groovy class, and test it using JUnit and pure Java code.
- "Jump into JUnit 4" (Andrew Glover, developerWorks, February 2007): This tutorial shows you how to leverage the new features in JUnit 4 enabled by annotations, including parametric tests, exception tests, and timed tests.
- "Discover XMLUnit" (Andrew Glover, developerWorks, December 2006): Developers are natural problem solvers, so it makes sense that someone has come up with an easier way to validate XML documents. This article introduces XMLUnit, a JUnit extension framework that meets all your XML validation needs.
- "Effective Unit Testing with DbUnit" (Andrew Glover, OnJava, January 2004): Writing unit tests first can be impractical when your code will depend on access to a database. Enter DbUnit, which allows you to write simple XML files to fill in for the yet-to-be populated database for testing purposes.
- Sun JDK 1.5 or later: You'll need at least version 1.5.0_09 to follow the examples in this tutorial.


text:
Like what we're doing? Want to carry custom products?
Use the form on the right to contact us. We'd love to hear from you!
123 Street Avenue, City Town, 99999
(123) 555-6789
You can set your address, phone number, email and site description in the settings tab.
Link to read me page with more information.

subset: commoncrawl


text:
A Step away to the perfect stayKoh Chang Cliff Beach Resort hospitality and the area's crystal clear water and private whit sandy beaches impress visitors. Koh Yuak famous tourist snorkeling area are just across the resort. Surrounded by National Park and coconut plantation with cliff view make it's a memorable holiday for everyone.
Koh Chang Cliff Beach features 16 rooms with balcony and is located in a very quiet part of Koh Chang (Kai Bae Beach) ideal for luxury walk around the village and seashore. Let nature take over your spirit sand enjoy our beachside sunbath, experience great way of relaxing yourself.
A glimpse of paradise, this resort is also a home away from home !With every delight at your fingertips, the true spirit of escape is undeniably natural here. Nestled within the surroundings are 2 swimming pools, one ideal for children, and one cliff-top infinity pool which host an amazing sunset view point! Families will enjoy activities such as boat rides, beach visits and elephant riding to name but a few, whereas the more adventurous traveler can experience guided treks through Koh Chang Natural Park, water sports and scuba diving.
Dining options range from delightful tastes of the Thailand, in the resort's own relaxing restaurant, to the various international foods available within the vicinity.
Mandalay Standard
These rooms provide a basic and clean living for traveler, equip with an air conditioning, refrigerator and an en-suite bathroom.
They are located on the opposite side of the road from the main resort but still only a couple of minutes walk to the beach. Being on the door step of Kai Bae Beach, it's within an easy reach to all the amenities.
Seaview Poolside Superior
These rooms are situated only a few steps from the swimming pool and beach front. The room command a good view of the sea, where you are able to relax on the balcony and enjoy the surrounding nature the resort has to offer.
Cliff View Superior
These rooms are perched on the cliff face commanding a spectacular view of the sea below. With it's overhang balcony, one could lounge away the day and watch the sunset set over in the distance.
Cliff View Deluxe
The Cliff View Deluxe Rooms are the perfect stay for that special romantic escape. Each and every room has a contemporary Thai feel, and provides that extra bit of luxury! The semi-open bathroom allows lights to flow throughout the room creating a sense of exotic coziness.
Lotus Family Bungalow
These suites feature over-sized bedroom with a separate living area. All suites have a large decking area outside for you to enjoy the fabulous lush garden view, while being only a short distance away from the beachfront.
Deluxe Pool Villa
Deluxe Pool Villa offers a small separate reading area with lounger, and large patio doors which open up onto its terrace where you can relax by the 3.5m x 4m private pool with Jacuzzi jets, and a lush view of the hills in the national park.
Thai House
The perfect stay for those looking for the ultimate romantic escape. These individual unit are set amongst the tropical tree and perched on the cliff face to provide a private romantic escape in a beautiful surrounding.
2 Bedroom Beach Villa Seaview
This unit offers perfect luxury for newly weds or those looking for the private romantic getaway. The unit is raised up to offer a commanding view of the beach below with an expansive bedroom and balcony so that you will never have to leave your room.
Coco Restaurant
Open all day and evening serving food and drinks. Begin your evening with a frosty drink, your favorite Thai beer or wine at our casual waterside cafe.
The restaurant is located on the sea front, with a large decking so you can enjoy dining either inside or out. Start your day with an early cup of coffee and buffet breakfast. Lunch and dinner are simple but satisfyingly scrumptious - we have a broad menu of Thai favorites, including homemade soups, curries and Thai deserts. Our European selection of sandwiches, burgers, pasta and pizza is also popular. Seafood is of course, always on the menu!
The open-air restaurant allows you to admire the view and feel the ocean breeze while enjoying a relaxing lunch or romantic dinner on the beach... This is paradise as you have never experienced it before!.
|Beach Pool
|Cliff top Infinity pool
|Cliff top Infinity pool
|Massage House
|Relax Corner
|Koh Chang is located on the east side of the Gulf of Thailand. The island is only 2 hours away from the border of the Cambodia, therefore many travelers stop by Koh Chang before they go to Cambodia to renew their visa.


text: Harry (Rob Estes) and Debbie (Lori Loughlin) inform Annie (Shenae Grimes) and Dixon (Tristan Wilds) about Harry's son that was given up for adoption nearly 22 years ago. While Dixon doesn't seem bothered by the information, Annie releases her frustration and anger at a sleepover with Naomi (AnnaLynne McCord), Silver (Jessica Stroup) and Adrianna (Jessica Lowndes). The sleepover quickly turns into a house party with guys and drinking games. Meanwhile, Annie and Ethan (Dustin Milligan) decide to hide their relationship from their friends and Dixon opens up to Silver (Jessica Stroup) about his latest family issues. Adrianna and Navid (Michael Steger) continue to get close until she misunderstands his intentions. Now that Ryan (Ryan Eggold) is in on Kimberlys (guest star Jessica Lucas) secret, the two can no longer control their desire for each other but are oblivious when a student observes their actions.


text:
- Event Calendar
- Online Registration
- Brochure
- Aquatics
- Parks
- Recreation
- Senior Center / Active Adults
- Reservations
- RV Park
- Parks & Recreation Staff
- Parks & Recreation Commission
- Department Forms
- FAQs
Park Info
Last Updated on Thursday, 24 January 2019 12:00
The City of Pullman park system has a rich history of community support. The first Pullman Park was established in 1903 on Pioneer Hill later to be named Kruegel Park. The first parks commission was established in 1906 and from that time several parks have been added to Pullman with a policy to "have a playground on each hill in Pullman." Many Pullman parks have developed been on donated property including Kruegel, Woodcraft, Lawson Gardens, Mary's Park (under construction), Terre View, Itani, and Petry Natural Area. The generosity of Pullman residents to donate property and resources for parks has become a tradition.
The City of Pullman boasts more than 100 acres of parkland, and 8 miles of pathways linked to the 8 mile Bill Chipman Palouse Trail that runs between Pullman and Moscow. The Downtown Riverwalk, the newest trail link to beckon walkers in the Pullman Parks and Recreation Trail System.
The passage of local Proposition No. 1 in 1999 funded expansion of the Bill Chipman Trail along the Palouse River into Pullman. Recent developments have been the additions of Terre View in 2003, Petry Park in 2005 and the development of Itani Park which began in 2006 and will be continuing through 2008. The Pullman Aquatic and Fitness Center construction was fully funded by private donation and opened to the public in 2000. The Pullman Aquatic and Fitness Center is owned by the Pullman School District and operated by the City of Pullman through an inter-local agreement. The formation of the Metropolitan Park District was established by a vote of Pullman Citizens in 2002, for a continuous funding source for Parks and Recreation programs and development. In 2007 the citizens of Pullman passed a new Proposition No. 1 initiative for improvements to park restrooms at Kruegel Park, Sunnyside Park and the City Playfields, additional trails expansion to the Maple Street Extension, Palouse Highway, and Johnson Road trails. In addition to new ballfield lights at the City Playfields.
The Pullman School District is a significant partner in community access to recreational facilities. School playgrounds, gymnasiums and athletic fields are used for City sponsored recreation programs throughout the city. In 1990, the City of Pullman provided funding to enlarge the gym at Sunnyside Elementary in exchange for community access during non-school use. After constructing a new elementary school on Pioneer Hill, the school district offered half of the old Franklin Elementary School to the City for use as a community center. The City remodeled the 1957 portion of the building into the 8,000-square-foot Pioneer Community Center, which opened to the public in 2000.
Washington State University (WSU) has also been a partner in community access to recreation facilities having participated in the Cougar Plaza mini-park and extension of the Bill Chipman Trail.
Park Regulations
- Park Hours - Dawn to Dusk
- Property Damage - No person shall deface, disfigure, break, cut, tamper with, displace or remove from any park, park property, either permanent or temporary.
- Dogs
- Owners shall remove all waste deposited by his or her animal in all areas of the parks.
- Dog shall be leased at all times while in city parks.
- No dogs allowed in Lawson Gardens, Harrison Tot Lot, or in any of the city cemetery. Per City Code 9.20.
- Vehicles - Vehicle parking is only allowed in designated areas. No vehicles are allowed to park on any grass areas without written permission from the Parks & Recreation Dept
City Playfield
820 South St. Situated along the South Fork of the Palouse River are the three softball fields (Thatuna, Bowman, and Wiley) that constitute the Pullman City Playfields (8.66 acres). This is the main athletic facility for Pullman's summer sports. A jogging track, exercise stations, volleyball standards, batting cage, picnic tables, drinking fountains and restrooms are also part of this athletic complex. The land for the City Playfield was dedicated to the city in 1941 by Henry Cole. Wiley Field was lighted in 1979, Bowman Field in 1985 and Thatuna Field in 2007.
Conservation Park
The City's "old nursery" site having outgrown its initial purpose made its transformation into the Conservation Park as a result of WSU student Angie Kenney's Master Thesis; Environmental and Societal Benefits of Conserving Open Space: An in Depth Analysis and formal Park Proposal for Pullman, Washington. The Boy Scouts have improved trails and made the initial improvements to the entrance site at the western terminus of Darrow Street, Park staff added a pergola and volunteers from Windermere Realty installed the landscape. Cub Scouts have added plantings and a bench site overlooking the Palouse River. The future vision includes pedestrian connections to Cooper Basin, Military Hill, and Grand Avenue Greenway.
Harrison Tot Lot
337 Harrison Street. Harrison Tot Lot is designed specifically for toddlers and very young children. All equipment is colorful, imaginative and geared for use by young families (0.233 acres). Casual seating areas, picnic table and BBQ further enhance this little park.
Itani Park
Rafik and Mary Sue Itani donated this natural linear park to the City in 1997 (7.45 acres). Development of the park began in 2006. In 2010 a small gazebo was constructed in the park.
Kruegel Park
705 Dilke. Originally donated to the city in 1958 by William C. Kruegel, the park has a lovely grove of shade trees that border the spacious picnic shelter and barbeque area (7.95 acres). Overlooking two tennis courts is an expansive playground which includes swings, and large sand area with climbing equipment. A small football field, little league baseball diamond, soccer field, volleyball standards and restrooms complete the facilities available at this lovely park.
Lawson Gardens
705 Derby. In 1985 Gerald Lawson, a local farmer, donated the land and development funds for this beautiful formal garden complex (13 acres). The garden was dedicated in 1987 to the memory of his wife, Alice. Oriented around a large reflecting pool and gazebo, seasonal plantings of colorful annuals accent the walkways and grassy area. In 1990 the Pullman Rotary Club donated funds for development of a circular rose garden which was planted in 1991-92 with 600 assorted rose bushes. The Perennial Garden was planted along the east side of the garden in 1991 and provides unique and colorful displays year round.
Military Hill Park
500 NW Larry. Set on Military Hill overlooking the fields of the Palouse, Military Hill Park is a shared facility with Pullman High School (25 acres). There are six tennis courts, two baseball diamonds, one playfield, a children's playground, picnic shelter, barbeques and restroom facilities. Surrounding the park is an extensive exercise trail. Development of Military Hill Park was completed in 1974 with the help of I.A.C. Funds. Quann Field, the primary baseball diamond, was outfitted with lights in 1979 and new bleachers were installed in 1992.
McGee Park
1220 Lybecker Street – off Stadium Way. Land for this park near W.S.U. was acquired in 1964 (3.04 acres). McGee park has a softball diamond and fenced basketball court for youth. The basketball court was donated by a local family to be enjoyed by the youth of the community. A large picnic shelter and BBQs are situated near the children's playground and restroom facilities.
Reaney Park
590 Reaney Way. In 1910 Reaney Park was the site of a roller rink and livery stable for W.S.U. students (1.64 acres). The city purchased the park site from Albert and Phebe Reaney in 1914. The bandstand was constructed and native buckeye trees planted in 1915. As more land was purchased the first swimming pool was built (1917). In the 1940's the park even included a small golf area. Reaney Park is the home of the National Lentil Festival and the Reaney Park Concert Series on summer evenings. Our community's only outdoor pools are located at the west end of the park and an extensive playground area wraps around the park perimeter.
Spring Street Park
325 Spring. Located near Reaney park, the park includes a skate board facility, and public restrooms (2.75 acres). The park has a trail link to the Bill Chipman Trail. Benches are located along the tranquil Palouse River for patrons to enjoy a quite moment with nature.
Sunnyside Park
147 Cedar St. Home of Pullman's yearly Fourth of July celebration, this expansive park rolls with the natural terrain of the Palouse (25 acres). Cradled below grassy knolls are two ponds fed by a waterfall and connected by a babbling creek. Graceful willows dip into the ponds and is home to assorted ducks and turtles. Development of Sunnyside Park was completed with the help of I.A.C. Funds in 1974. There is a large picnic shelter and barbeque overlooking the ponds and an adjoining children's playground. Two tennis courts, a little league baseball field, volleyball standards, disc golf course and trails complete the athletic facilities available. The south side of the park, previously a nursery, is now used for community gardens which are available for summer rental through the Parks and Recreation office.
Terre View Park
325 NW Terre View Drive. The park was donated by Ed and Mary Schweitzer in 1999 (3.25 acres). The park includes a picnic shelter, playground, wetland pond area, and public restroom.
Woodcraft Park
675 South St. Nestled in a quiet southeast neighborhood and sheltered by shade trees, Woodcraft park is primarily a peaceful picnic area (0.84 acres). The park land was donated to the city in 1946. A two-person swing and restroom facilities are on the premises.
Pullman City R.V. Park
775 South St. The R.V. park is tucked along the Palouse River within walking distance of downtown Pullman and W.S.U. (19 spaces). All 19 spaces have full hookups for water, electricity, sewer and cable TV. Tent spaces with tables and barbeques are also available (first-come-first-serve). Chemical toilets are on the premises. Reservations may be made in advance by calling (509)338-3227.


text:
Two-level luxury condo in Pacific Heights
Condominium offers skyline views and contemporary design
When Riaz Taplin started redesigning a condo building in San Francisco, he wanted to create a space on par with the Four Seasons or the St. Regis Hotel. The founder of Artthaus Design brought in consultants for everything from acoustics to waterproofing during the construction of the three-unit building in Pacific Heights.
The recently finished structure now only has one unit left on the market: a two-level condominium featuring a private, landscaped roof terrace, outdoor kitchen and floor-to-ceiling windows showing off sweeping views of the San Francisco skyline.
"I've done about 30 projects in the last decade, but this is the first one I've done with dead-on views of the city," Taplin said. "We created something that has the ease and function of the Four Seasons but is in Pacific Heights."
To create a light and airy feeling in the condominium, double bleached white oak floors and large windows were installed in the three-bedroom unit. The building's lobby includes a herringbone patterned marble floor and artwork designed by Taplin and his sister. Horizontal steel railings create a graceful linear design inside, while a living wall with various plantings outside the building is starting to blossom.
Full seismic upgrades and a new foundation were installed, and each level has acoustic finishes to minimize the sound between residents, said Max Armour, one of the listing agents for 2064 Jackson St.
"No one wants to hear their neighbor playing music or stomping around," he said.
The condominium includes a Heat N Glo gas fireplace with limestone surround in its living room, and cabinetry designed by Artthaus conceals a flat-screen television. Floor-to-ceiling sliding glass doors open up to unobstructed views of San Francisco Bay.
The nearby dining area can easily accommodate large gatherings, while a glass-enclosed alcove provides a casual setting for two.
Considered to be the heart of the unit, the open kitchen includes marble counters, Dada cabinets and appliances manufactured by Viking, Sub-Zero and Wolf. The kitchen also offers a butler's pantry and wet bar with a temperature controlled wine cooler.
Down a spacious gallery - which provides ample space for displaying artwork - are two bedrooms and a marble bathroom with shower.
Like the living room, the master suite boasts a limestone fireplace and Artthaus cabinetry. It overlooks Pacific Heights and includes a spacious dressing room with a Molteni double wardrobe and additional storage. A jetted tub and glass-enclosed shower highlight the master bathroom, while marble surrounds and a double-ash vanity create a luxurious backdrop.
Up a staircase with built-in display niches rests the pentroom, which opens to a landscaped roof terrace featuring an outdoor kitchen and barbecue.
"It could be the largest private terrace in San Francisco," Taplin said.
2064 Jackson St. also comes with a two-car garage and concierge service, as well as a janitorial service that cleans the building's public areas every day.
Listing agents: Malin Giddings, TRI Coldwell Banker. (415) 531-5033. firstname.lastname@example.com; Max Armour, TRI Coldwell Banker. (415) 290-6058. email@example.com.
Address: 2064 Jackson St., Pacific Heights, S.F.
Price: $5.995 million
Features: Three-bedroom, 2.5-bathroom two-level condominium with marble finishes, outdoor kitchen and private, landscaped roof terrace.
Open house: 2 to 4 p.m., Sunday


text:
Bournemouth SignLove British Lifestyle
This Vintage Rail metal sign is a great design piece for inside your home and outside. It is designed with a British style print, and made from aluminium, not soft tin, to last a lifetime.
High quality metal prints made in the UK. Each with 4 drill holes for secure fixing to walls.Free worldwide shipping.


text:
Learn how to research and develop relationships with potential funding sources, organize grant writing campaigns, and prepare proposals.
Learn More>>
Gain a full understanding of the criteria funders use to determine whether your grant proposal gets funded or rejected.
Learn More>>
Complete the form below and click the Reset Password button. If
we find your password, we'll send password reset instructions to the e-mail address
we have on record for you.


text:
The Most Judged Woman in America
Wendy Davis did make a mistake. She thought that we were ready for a single mother.
That any American politician is truly self-made is a pretty hilarious notion. While some start out poor or disadvantaged, along the way every political aspirant benefits from mentors, donors, true believers, hangers-on, sycophants, consultants, friends, family, fund-raisers—and, in the case of male politicians, wives.
Maybe the wife holds down things on the home front, raising the kids and ensuring that the politician can present himself as a family man and therefore stable and upstanding. Maybe she brings in the earnings during his early, less lucrative years, then gives up her job when the demands of his career make hers unsustainable. Maybe she campaigns alongside him, listening to the same speech for hundreds of hours, channeling the love of the crowd as she gazes toward him. Maybe she has inherited wealth that provides him with material ease and lucrative connections. Maybe, at a certain point, he divorces her, thanks her for her service—or doesn't thank her—and re-marries.
Story Continued Below
The point is, in the complex narrative of dependence and assistance and ambition that is the ordinary rise to political prominence, there are some life stories—the male life stories—that are so familiar, so common, we accept them as archetypal.
Given that winning political office requires help, it was probably a mistake for Wendy Davis, the Texas state senator who is now running for governor, to insist quite so ardently that she got where she did through her own pluck and determination. Davis, a Democrat who rose to national prominence during a dramatic filibuster of a restrictive abortion bill in the Texas legislature last year, is now campaigning for her state's highest office on a life story that has her rising from humble beginnings through "hard work and optimism," as she told NBC, then pursuing higher education, as her campaign website says, with "the help of academic scholarships, student loans, and state and federal grants." Now that she is in a high-profile and hotly partisan race, it has come out that she also benefited from the moral and financial support of her second (now ex) husband, Jeff Davis. In the process, though, behavior we would expect and hardly notice in a man is being portrayed as freakish and problematic in a woman.
The kerfuffle began last weekend, with the publication of a profile in the Dallas Morning News that filled out gaps in her story, and continued all week as Davis was spun by her critics as a social climber, an ingrate, a neglectful mother. She has been chastised for starting out in her marriage as a dependent (golddigger!), and finishing it as a lawyer so financially successful that she was the one paying child support to her ex-husband (careerist harpy!). While this professional and relational arc is seen by some as deviant and unattractive, I'll tell you what strikes me, reading her life story: how common it is. Countless women of Davis's generation—she was born in 1963—grew up expecting one kind of marriage and then found themselves living another. Countless women started out in marriages where they were the junior partner, then at some point—to their own surprise as much as anybody's—pulled ahead. In that way, Wendy Davis's life is ordinary, but it's something we haven't come to terms with as a culture.
While some of the details have yet to fully emerge, most versions of her life seem to agree on this: Davis's parents split when she was little. Life was tough; by age 14 she was working to help her mom, who has the wonderfully Dickensian name of Ginger Cornstubble, and her siblings. At 17 she moved in with her boyfriend, then married and had a daughter; that marriage soon ended and for a time she and her daughter continued to live in the trailer where the family had formerly resided together. According to the Morning News, Davis worked as a receptionist in a pediatrician's office, attended community college and waitressed in her dad's Fort Worth dinner theater—presumably learning, like many women, that the wage scale of the pink-collar professions was established back in the day when a woman's income was intended to supplement that of a breadwinning husband, and has not been adjusted upward. During this time she met and took a liking to Jeff Davis, a lawyer who was 13 years older; they dated, married, had a daughter of their own.
With the support of Jeff Davis, who comes across in his comments as good-natured and generous, Wendy Davis was able to find her way into a life more materially comfortable and expansive. But it wasn't a coddled, Real-Housewives-type existence of fluffy dogs and spa days. Instead, she went on to Texas Christian University, where she had financial aid and scholarships, did well, and from there to Harvard Law School. Jeff Davis reportedly paid for his wife's last two years in college, cashed in his 401(k) to send her to law school, was the primary caregiver while she was away studying and took out a loan so she could finish. In a statement, Wendy Davis confirmed that he cashed in the retirement fund, but says "they" took out loans and that the children lived with her during her first year at Harvard, after which she commuted back and forth and her mom helped watch the girls. Though no phrase existed for what Wendy Davis was doing at the time, now we have one: She was leaning in.


text:
The environmental impact assessment (EIA) general assembly concluded that a road construction plan, which has sparked protests over a perceived threat to endangered leopard cats in Miaoli County, should be returned to an EIA specialists' meeting for further review.
About 400 people gathered outside the Environmental Protection Administration (EPA) building in Taipei yesterday afternoon to protest against the plan.
The protesters included environmental activists, civic groups, academics and many students and netizens who responded to a call made by the Taiwan Society for the Prevention of Cruelty to Animals (Taiwan SPCA) through Facebook, asking the public to help save the leopard cats by blocking the road construction plan.
The planned 8.28km bypass road for Provincial Highway No. 13, stretching from Tongluo Township (銅鑼) to Sanyi Interchange of Freeway No. 1, first gained EIA approval in 2003, but after construction delays, the local government proposed an EIA review on amendments made to the plan.
Environmentalist Pan Han-shen (潘翰聲) said the planned road would cut through a very important habitat for the leopard cats.
Their population is estimated to be only between 400 and 600 in Taiwan, Pan said, adding that their remaining habitats in Miaoli County are being destroyed by several development projects.
Kurtis Pei (裴家騏), a professor at National Pingtung University of Science and Technology's Institute of Wildlife Conservation, said records from about 100 years ago showed the leopard cats were found everywhere in the nation, but research in the past decade showed that they can only be found in the lower mountainous areas of Miaoli and Nantou counties.
"Being threatened by many development projects, the leopard cats are fleeing in all directions, but they might not be able to find suitable new homes," he said. "I believe the many transportation specialists can come up with better alternative plans to solve traffic problems without destroying the leopard cats' habitats."
Shanyi resident Yeh Chi-hao (葉旗豪) said the local government could expand Provincial Highway No. 13 or build more parking lots to solve traffic congestion problems that only occur on weekends, instead of constructing a bypass.
Hundreds of Miaoli residents, led by Sanyi Township (三義鄉) Mayor Hsu Wen-ta (徐文達), arrived at the EPA building to voice their support for the local government's plan.
Just before the meeting began, Miaoli County Commissioner Liu Cheng-hung (劉政鴻) also arrived, prompting protesters to shout slogans such as "Liu Cheng-hung, step down," and "Leopard cats don't only belong to Sanyi, but to all of Taiwan."
During the meeting, Liu said the local government has already planned a 40-hectare area as ecological compensation for the endangered animal, which "should be very helpful to the ecology."
Liu said the local government would allocate a budget for species conservation, but "we need local development, because Shanyi is a township of tourism."
The Forestry Bureau said its three-year research showed Miaoli has the largest leopard cat population, so it is not in favor of the construction project, but if the road is necessary, then an elevated road would be better because it would prevent habitat fragmentation.
A committee member asked whether the local government's plan to set up tunnels as ecological corridors for leopard cats to move from one area to the other would be effective, because no study has proved the method's effectiveness.


text:
Kill the Buzz! Now!
October 28, 2008 40 Comments
I clicked on the headline link because it looked interesting.
Then my jaw dropped, 12 inches per paragraph, until I had to pick it up off the floor.
It couldn't be. A PR gift! The most perfect press release illustrating Wordslaughter, 1st degree. The most astonishing pile-up of incomprehensible buzz-words and meaningless jargon ever assembled in one place! Surely it was a joke, a parody?
Nope. It's for real – read it for yourself.
Here is a sample of the blizzard of words, phrases, mantras, and business pixie-dust concepts contained in this inspired document:
- …a framework for pharmaceutical companies to develop a new value proposition for sales into medical group practices…the approach positions a pharmaceutical component as the keystone to an entire ecosystem of businesses marketing to physicians…Commercial models are designed and in turn "optimized" to promotional response curves…commodity inputs…has reached its productivity frontier…Opportunity space for value innovation…intimacy of interactions in the business ecosystem…We are unique with a framework to help clients innovate, differentiate their strategies, and shape new ideas at a system level.
But wait…there's more!
The website copy was written with the same attention to jargon detail. If you thought the above phrases are parody-worthy, just head on over to the on-line mothership and try to grasp the 30-second elevator speech. Or, better yet, try to grasp anything.
- The concept is a forward-thinking approach to synchronize action in a complex environment and build new knowledge to improve decision making. It looks at the whole of a marketing game with new planning, sense-making, and decision-making strategies.
Marketing and PR should not be done by philosophers and engineers. Because the end result is not promotion, but self-generated spoof!


text:
Professional Development
Job Seekers, Welcome to Public Health CareerMart
Job seekers, recently scammers have been targeting job boards to create fake accounts. If an employer contacts you and ask for personal information or set up a Yahoo account, please disengage and contact firstname.lastname@example.com.
The job you tried to view is no longer active.
See similar jobs below or perform a new job search.
See similar jobs below or perform a new job search.
Sort By
11,590 'registered OR nurse OR med/surg OR acute OR prn/nights OR STATECODE:"TX"' Jobs
Texas Rehab Arlington, Texas
Kindred Healthcare
3 Weeks Ago
RN Job Fair Open Interview day Every Thursday! 10a -2p Registered Nurses ICU Kindred Hospital Spring Houston
Spring, Texas
Kindred Healthcare
5 Days Ago
Kindred Healthcare
3 Weeks Ago
Kindred Healthcare
4 Weeks Ago
Registered Nurse Medical Surgical -Full Time Days Kindred Hospitals Houston Float Pool Program $7500 Sign on bonus
Spring, Texas
Kindred Healthcare
1 Week Ago
Powered By


text:
You will read Ayn Rand, you whim-worshipper!
BOISE – Coeur d'Alene Sen. John Goedde, chairman of the Idaho Senate's Education Committee, introduced legislation Tuesday to require every Idaho high school student to read Ayn Rand's "Atlas Shrugged" and pass a test on it to graduate from high school.
When Sen. Bob Nonini, R-Coeur d'Alene, asked Goedde why he chose that particular book, Goedde said to laughter, "That book made my son a Republican."
Goedde said he doesn't plan to press forward with the bill, but it was formally introduced in his committee Tuesday on a voice vote. He said he was sending a message to the State Board of Education, because he's unhappy with its recent move to repeal a rule requiring two online courses to graduate from high school, and with its decision to back off on another planned rule regarding principal evaluations.


text:
Watch the clip about child poverty which was made as part of the "End Child Poverty" campaign by Eurochild and its members. więcej
The 2010 European Year for Combating Poverty and Social Exclusion is coming to an end and the official closing ceremony is taking place on the 17 December in Brussels. więcej
Throughout the Year Ambassadors were key in raising visibility. They attended workshops, festivals, participated, spoke, gave testimonies, moved, came, went, travelled and much much more więcej
Europe seen through children's eyes" has been the motto of an artwork school competition organised by the Representation of the European Commission in Romania and dedicated to the European Year 2010 więcej
The CEV Symposium "Volunteering as a means of empowerment and social inclusion – A bridge between the European Years 2010 and 2011" took place in Brussels in the framework of the Belgian EU Presidency, on 6-8 December 2010 więcej
1-5 z 159


text:
Home > Sunglasses > Alexander McQueen > AM0146S (001)
AM 0146S is available in 2 additional attractive styles
Size and availability
Low prices
Low prices
AM0146S/001 Ophthalmic Glasses
AM0146S is a fashion statement, for which sunshine is not necessarily required, because these sunglasses enhance your natural radiance turning night into day. The new Alexander McQueen underlines that you are a trendsetter. For the current season the renowned label sets the standards with its collection for 2019. Would another colour not be a better match for your favourite outfit? Check also the other styles of AM0146Sin our 2018, and 2019 Alexander McQueen range.
With no frills and state-of-the-art materials and craftsmanship, these men's glasses stand for stylish design and self-confidence. The square frame is a classical shape, highlighting the straightforwardness of the personality. This brand of sunglasses, of course, also provides your eyes with optimum UV400 protection.
The next shipment is on its way, so we will have your Alexander McQueen back in stock very soon. We hope the unbelievably low price will be a consolation for the short wait. And because Edel-Optics is a paradise for bargain hunters, you can get this top model at an incredibly low price. What is labelled as "in the sale" at other online shops, is for us "all-day-everyday" prices.
Don't hesitate to call us at
payment methods
Credit Card
Bank Transfer


text:
Items to be covered in this edition:
I. Important Dates
II. Funding Opportunities
III. Welcome to New Faculty and Staff
IV. Faculty News
VI. Faculty Publications and Presentations
Read the October 2013 issue of the Department of Pediatrics Newsletter here.
Please let us know of your latest publications, awards, and honors by emailing: firstname.lastname@example.com.
1959 NE Pacific St.
Box 356320
Seattle, WA 98195-6320
4800 Sand Point Way NE
Seattle, WA 98105
Copyright © 2019 Department of Pediatrics, University of Washington. All rights reserved.
Privacy |
Terms | Website Feedback | Site Map