ERXRestRequestHandler Class Reference

Inherits com::webobjects::appserver::WORequestHandler.

Collaboration diagram for ERXRestRequestHandler:

Collaboration graph
[legend]

List of all members.

Public Member Functions

IERXRestDelegate delegate ()
 ERXRestRequestHandler (IERXRestAuthenticationDelegate authenticationDelegate, IERXRestDelegate delegate, IERXRestResponseWriter defaultResponseWriter, IERXRestParser defaultRequestParser)
 ERXRestRequestHandler (IERXRestAuthenticationDelegate authenticationDelegate, IERXRestDelegate delegate)
WOResponse handleRequest (WORequest request)
void removeRequestParserForType (String type)
void removeResponseWriterForType (String type)
void setRequestParserForType (IERXRestParser requestParser, String type)
void setResponseWriterForType (IERXRestResponseWriter responseWriter, String type)

Static Public Member Functions

static final ERXRestRequestHandler createUnsafeRequestHandler (boolean readOnly, boolean displayToMany)
static final ERXRestRequestHandler register (IERXRestAuthenticationDelegate authenticationDelegate, boolean displayAllProperties, boolean displayAllToMany)
static ERXDefaultRestDelegate register (IERXRestAuthenticationDelegate authenticationDelegate)
static void register (IERXRestAuthenticationDelegate authenticationDelegate, IERXRestDelegate delegate)
static void register (ERXRestRequestHandler requestHandler)

Static Public Attributes

static final String Key = "rest"
static final Logger log = Logger.getLogger(ERXRestRequestHandler.class)

Protected Member Functions

EOEditingContext newEditingContext ()
IERXRestParser requestParserForType (String type)
IERXRestResponseWriter responseWriterForType (String type)

Private Attributes

IERXRestAuthenticationDelegate _authenticationDelegate
IERXRestParser _defaultRequestParser
IERXRestResponseWriter _defaultResponseWriter
IERXRestDelegate _delegate
NSMutableDictionary< String,
IERXRestParser
_requestParsers
NSMutableDictionary< String,
IERXRestResponseWriter
_responseWriters


Detailed Description

ERXRestRequestHandler is the entry point for REST requests. It provides support for registering an authentication delegate, a processing delegate, and a per-entity response writer.

If you just want to play around with REST, you can use the "unsafe" delegates. These delegates ARE NOT suitable for deployment (and in fact will not function in deployment). They are a major security hole, but exist just to provide wide-open access to developers who are interested in exploring the features of the ERRest framework.

Please note that the stock Apache adaptor shipped with WebObjects 5.3 is not capable of handling the PUT and DELETE HTTP methods, you will have to use the adaptor from WebObjects 5.4 or the one from Project Wonder.

Unsafe Development Setup Example

To use the unsafe development example delegates, you can add the following code to your application constructor:

 registerRequestHandler(ERXRestRequestHandler.createUnsafeRequestHandler(true, false), "rest");
 

Real-world Setup Example

In a real scenario you will not want to use the unsafe variants of the various delegates. Instead, you will want to provide custom implementations.

 ERXDefaultRestDelegate restDelegate = new ERXDefaultRestDelegate();
 restDelegate.addDelegateForEntityNamed(new CompanyRestEntityDelegate(), Company.ENTITY_NAME);
 restDelegate.addDelegateForEntityNamed(new PersonRestEntityDelegate(), Person.ENTITY_NAME);
 IERXRestAuthenticationDelegate authenticationDelegate = new MyCustomRestAuthenticationDelegate();
 IERXRestResponseWriter responseWriter = new ERXXmlRestResponseWriter();
 registerRequestHandler(new ERXRestRequestHandler(authenticationDelegate, restDelegate), "rest");
 

Once you have the request handler registered, you can explore the rest interface using an HTTP client like 'curl'. Note that the examples below will not work on your own application unless you provide entities with the same design.

Get a list of all the Site objects

 curl -s http://127.0.0.1/cgi-bin/WebObjects/YourApp.woa/rest/Site.xml?membershipTicket=someAuthToken
 

 HTTP Status Code: 200
 <Sites type = "Site">
   <Site id = "100">
     <title>Site #1</title>
     <bulletins type = "Bulletin">
       <Bulletin id = "200"/>
       <Bulletin id = "201"/>
       <Bulletin id = "202"/>
     </bulletins>
   </Site>
   <Site id = "101">
     <title>Site #2</title>
     <bulletins type = "Bulletin">
       <Bulletin id = "215"/>
       <Bulletin id = "230"/>
       <Bulletin id = "243"/>
     </bulletins>
   </Site>
 </Sites>
 

Get a single site from the Site list

 curl -s http://127.0.0.1/cgi-bin/WebObjects/YourApp.woa/rest/Site/100.xml?membershipTicket=someAuthToken
 

 HTTP Status Code: 200
 <Site id = "100">
   <title>Site #1</title>
   <bulletins type = "Bulletin">
     <Bulletin id = "200"/>
     <Bulletin id = "201"/>
     <Bulletin id = "202"/>
   </bulletins>
 </Site>
 

Get a single site from the Site list (that doesn't exist)

 curl -s http://127.0.0.1/cgi-bin/WebObjects/YourApp.woa/rest/Site/112.xml?membershipTicket=someAuthToken
 

 HTTP Status Code: 404
 There is no Site with the id '112'.
 

Get a single site from the Site list (that we can't see)

 curl -s http://127.0.0.1/cgi-bin/WebObjects/YourApp.woa/rest/Site/114.xml?membershipTicket=someAuthToken
 

 HTTP Status Code: 403
 You are not allowed to view the Site with the id '112'.
 

Get a list of the bulletins for that Site

 curl -s http://127.0.0.1/cgi-bin/WebObjects/YourApp.woa/rest/Site/100/bulletins.xml?membershipTicket=someAuthToken
 

 HTTP Status Code: 200
 <Bulletins type = "Bulletin">
   <Bulletin id = "200">
     <author type = "Person" id = "500"/>
     <title>Bulletin 1</title>
     <contents>Bulletin 1 Contents</title>
   </Bulletin>
   <Bulletin id = "201">
     <author type = "Person" id = "600"/>
     <title>Bulletin 2</title>
     <contents>Bulletin 2 Contents</title>
   </Bulletin>
   <Bulletin id = "202">
     <author type = "Person" id = "700"/>
     <title>Bulletin 3</title>
     <contents>Bulletin 3 Contents</title>
   </Bulletin>
 </Bulletins>
 

Get a single bulletin from the Bulletin list

 curl -s http://127.0.0.1/cgi-bin/WebObjects/YourApp.woa/rest/Site/100/bulletins/201.xml?membershipTicket=someAuthToken
 

 HTTP Status Code: 200
 <Bulletin id = "201">
   <author type = "Person" id = "600"/>
   <title>Bulletin 2</title>
   <contents>Bulletin 2 Contents</title>
 </Bulletin>
 

Update the title of a bulletin

 curl -X PUT -d '<Bulletin><title>Some random Bulletin!</title></Bulletin>' -s http://127.0.0.1/cgi-bin/WebObjects/YourApp.woa/rest/Site/100/bulletins/201.xml?membershipTicket=someAuthToken
 

 HTTP Status Code: 200
 

Try to break it -- Update a site with a bulletin document

 curl -X PUT -d '<Bulletin><title>Some random Bulletin Again!</title></Bulletin>' -s http://127.0.0.1/cgi-bin/WebObjects/YourApp.woa/rest/Site/100.xml?membershipTicket=someAuthToken
 

 HTTP Status Code: 403
 You tried to put a Bulletin into a Site.
 

Update the title of a site

 curl -X PUT -d '<Site><title>My Personal Site!</title></Site>' -s http://127.0.0.1/cgi-bin/WebObjects/YourApp.woa/rest/Site/100.xml?membershipTicket=someAuthToken
 

 HTTP Status Code: 200
 

Post a bulletin

 curl -X POST -d '<Bulletin><title>New Bulletin By Me</title><contents>This is the contents of my bulletin</contents></Bulletin>' -s http://127.0.0.1/cgi-bin/WebObjects/YourApp.woa/rest/Site/100/bulletins.xml?membershipTicket=someAuthToken
 

 HTTP Status Code: 201
 <Bulletin id = "7324">
   <title>New Bulletin By Me</title>
   <contents>This is the contents of my bulletin</contents>
 </Bulletin>
 

Delete a bulletin

 curl -X DELETE -s http://127.0.0.1/cgi-bin/WebObjects/YourApp.woa/rest/Site/100/bulletins/7324.xml?membershipTicket=someAuthToken
 

 HTTP Status Code: 200
 

Using it Programmatically

If you want to process the results of a REST call to a remote server on your local system (i.e. simple EO syncing), you can execute something like:

 EOEditingContext editingContext = ERXEC.newEditingContext();

 ERXDefaultRestDelegate restDelegate = new ERXDefaultRestDelegate();
 restDelegate.addDelegateForEntityNamed(new ERXUnsafeRestEntityDelegate(true), Manufacturer.ENTITY_NAME);
 ERXRestContext restContext = new ERXRestContext(context(), editingContext, restDelegate);

 String contentStr = ERXFileUtilities.stringFromURL(new URL("http://someserver/rest/Manufacturer.xml&quot;));
 ERXRestRequest restRequest = new ERXXmlRestRequestParser().parseRestRequest(restContext, contentStr, "Manufacturer");
 ERXRestKey restResponse = restDelegate.process(restRequest, restContext);

 editingContext.saveChanges();
 

This assumes your PK match across systems, which means you should probably be using UUID PK's for syncing unless it's only one-way and read-only on the client.

Author:
mschrag

Constructor & Destructor Documentation

ERXRestRequestHandler ( IERXRestAuthenticationDelegate  authenticationDelegate,
IERXRestDelegate  delegate 
)

Construct an ERXRestRequestHandler with a default response writer of ERXXmlRestResponseWriter.

Parameters:
authenticationDelegate the authentication delegate
delegate the rest delegate

ERXRestRequestHandler ( IERXRestAuthenticationDelegate  authenticationDelegate,
IERXRestDelegate  delegate,
IERXRestResponseWriter  defaultResponseWriter,
IERXRestParser  defaultRequestParser 
)

Construct an ERXRestRequestHandler.

Parameters:
authenticationDelegate the authentication delegate
delegate the rest delegate
defaultResponseWriter the default response writer to use
defaultRequestParser the default request parser to use


Member Function Documentation

static final ERXRestRequestHandler createUnsafeRequestHandler ( boolean  readOnly,
boolean  displayToMany 
) [static]

Creates an unsafe request handler for you to try out in development mode. THIS SHOULD NOT BE DEPLOYED (and in fact it will throw an exception if development mode is false).

Parameters:
readOnly if true, the unsafe read-only delegate will be used
displayToMany if true, to-many relationships will display by default
Returns:
an unsafe request handler

IERXRestDelegate delegate (  ) 

WOResponse handleRequest ( WORequest  request  ) 

Handle the incoming REST request. REST requests can have session ids associated with them as cookies or wosid query string parameters. Right now rendering type is not supported, but ultimately the file extension of the request will determine which renderer is used to render the response.

Parameters:
request the request

EOEditingContext newEditingContext (  )  [protected]

Returns a new editing context. If you want to override how an editing context is created, extend ERXRestRequestHandler and override this method.

Returns:
a new editing context

static final ERXRestRequestHandler register ( IERXRestAuthenticationDelegate  authenticationDelegate,
boolean  displayAllProperties,
boolean  displayAllToMany 
) [static]

Registers an ERXRestRequestHandler with the WOApplication for the handler key "rest" using an ERXDefaultRestDelegate, ERXXmlRestResponseWriter, and ERXXmlRestRequestParser.

Parameters:
authenticationDelegate the authentication delegate
displayAllProperties if true, by default all properties are eligible to be displayed (probably should only be true in development, but it won't really hurt anything). Note that entity delegates will still control permissions on the properties, it just defaults to checking all of them.
displayAllToMany if true, all to-many relationships will be displayed

static ERXDefaultRestDelegate register ( IERXRestAuthenticationDelegate  authenticationDelegate  )  [static]

Registers an ERXRestRequestHandler with the WOApplication for the handler key "rest" and an ERXDefaultRestDelegate.

Parameters:
authenticationDelegate the authentication delegate

static void register ( IERXRestAuthenticationDelegate  authenticationDelegate,
IERXRestDelegate  delegate 
) [static]

Registers an ERXRestRequestHandler with the WOApplication for the handler key "rest".

Parameters:
authenticationDelegate the authentication delegate
delegate the rest delegate

static void register ( ERXRestRequestHandler  requestHandler  )  [static]

Registers an ERXRestRequestHandler with the WOApplication for the handler key "rest".

Parameters:
requestHandler the rest request handler to register

void removeRequestParserForType ( String  type  ) 

Removes the request parser for the given entity.

Parameters:
type the type to disassociate

void removeResponseWriterForType ( String  type  ) 

Removes the response writer for the given entity.

Parameters:
type the type to disassociate

IERXRestParser requestParserForType ( String  type  )  [protected]

Returns the request parser for the given entity name.

Parameters:
type the type of request ("xml", "json", etc)
Returns:
the request parser to use

IERXRestResponseWriter responseWriterForType ( String  type  )  [protected]

Returns the response writer for the given entity name.

Parameters:
type the type of request ("xml", "json", etc)
Returns:
the response writer to use

void setRequestParserForType ( IERXRestParser  requestParser,
String  type 
)

Sets the request parser for the request type.

Parameters:
requestParser the request parser to use
type the type of request ("xml", "json", etc)

void setResponseWriterForType ( IERXRestResponseWriter  responseWriter,
String  type 
)

Sets the response writer for the request type.

Parameters:
responseWriter the response writer to use
type the type of request ("xml", "json", etc)


Member Data Documentation

final String Key = "rest" [static]

final Logger log = Logger.getLogger(ERXRestRequestHandler.class) [static]


The documentation for this class was generated from the following file:

Generated on Sat May 26 06:43:28 2012 for Project Wonder by  doxygen 1.5.8