
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.
To use the unsafe development example delegates, you can add the following code to your application constructor:
registerRequestHandler(ERXRestRequestHandler.createUnsafeRequestHandler(true, false), "rest");
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.
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>
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>
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'.
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'.
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>
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>
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
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.
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
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>
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
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"));
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.
| ERXRestRequestHandler | ( | IERXRestAuthenticationDelegate | authenticationDelegate, | |
| IERXRestDelegate | delegate | |||
| ) |
Construct an ERXRestRequestHandler with a default response writer of ERXXmlRestResponseWriter.
| authenticationDelegate | the authentication delegate | |
| delegate | the rest delegate |
| ERXRestRequestHandler | ( | IERXRestAuthenticationDelegate | authenticationDelegate, | |
| IERXRestDelegate | delegate, | |||
| IERXRestResponseWriter | defaultResponseWriter, | |||
| IERXRestParser | defaultRequestParser | |||
| ) |
Construct an ERXRestRequestHandler.
| authenticationDelegate | the authentication delegate | |
| delegate | the rest delegate | |
| defaultResponseWriter | the default response writer to use | |
| defaultRequestParser | the default request parser to use |
| 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).
| readOnly | if true, the unsafe read-only delegate will be used | |
| displayToMany | if true, to-many relationships will display by default |
| 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.
| 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.
| 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.
| 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.
| authenticationDelegate | the authentication delegate |
| static void register | ( | IERXRestAuthenticationDelegate | authenticationDelegate, | |
| IERXRestDelegate | delegate | |||
| ) | [static] |
Registers an ERXRestRequestHandler with the WOApplication for the handler key "rest".
| 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".
| requestHandler | the rest request handler to register |
| void removeRequestParserForType | ( | String | type | ) |
Removes the request parser for the given entity.
| type | the type to disassociate |
| void removeResponseWriterForType | ( | String | type | ) |
Removes the response writer for the given entity.
| type | the type to disassociate |
| IERXRestParser requestParserForType | ( | String | type | ) | [protected] |
Returns the request parser for the given entity name.
| type | the type of request ("xml", "json", etc) |
| IERXRestResponseWriter responseWriterForType | ( | String | type | ) | [protected] |
Returns the response writer for the given entity name.
| type | the type of request ("xml", "json", etc) |
| void setRequestParserForType | ( | IERXRestParser | requestParser, | |
| String | type | |||
| ) |
Sets the request parser for the request type.
| 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.
| responseWriter | the response writer to use | |
| type | the type of request ("xml", "json", etc) |
IERXRestParser _defaultRequestParser [private] |
IERXRestResponseWriter _defaultResponseWriter [private] |
IERXRestDelegate _delegate [private] |
NSMutableDictionary<String, IERXRestParser> _requestParsers [private] |
final Logger log = Logger.getLogger(ERXRestRequestHandler.class) [static] |
1.5.8