Wiki source code of ERRest Framework

Version 55.1 by David Avendasora on 2011/03/15 10:14

Show last authors
1 = Presentations =
2
3 * A presentation made by Mike Schrag on February 16th 2010 about ERREST. http:~/~/webobjects.mdimension.com/wonder/screencasts/ERRest-2010-02-16.mov
4 It's also listed on the [[Screencasts Page>>http://www.wocommunity.org/webobjects_screencasts.html]] on wocommunity.org, in [[iTunes>>http://itunes.apple.com/us/podcast/webobjects-podcasts/id270165303]] and in the [[Podcasts RSS Feed>>http://www.wocommunity.org/podcasts/wopodcasts.xml]].
5
6 * Mike also did a session about it at WOWODC West 2009.
7 You can get access to this session by purchasing a WebObjects Community Association membership.
8
9 * A session on ERRest integration with Dogo was made by Pascal Robert at WOWODC 2010.
10 You can also get this session by purchasing a WebObjects Community Association membership.
11
12 = Class names vs entity names =
13
14 A question was asked about situations where your EO class name is different from your entity name. Mike's answer was :
15
16 Everything internally is based on entity names. Your class name has very little to do with things other than your own source code. So for example:
17
18 routeRequestHandler.addDefaultRoutes("SamsSchool"); ~/~/ School.ENTITY//NAME//
19
20 Regardless, you will always have:
21 public class SamsSchoolController extends ERXDefaultRouteController {
22 ...
23 School school = (School) routeObjectForKey("samsSchool");
24
25 When those slides say "EntityName", they mean it :)
26
27 If you want to call it "School" to the outside, add this before you register the default routes for "SamsSchool":
28
29 ERXRestNameRegistry.registry().setExternalNameForInternalName("School", "SamsSchool"); ~/~/ "School", School.ENTITY//NAME//
30
31 After adding this, no other code changes. All you're saying is that the routes and type names that send over the wire should all say "School".
32
33 = WO HTTP adaptor =
34
35 The WO HTTP adaptor coming with WO 5.3 doesn't support PUT and DELETE operations, so you won't be able to use those two HTTP methods. You need to use either the 5.4 adaptor or the Wonder version of the adaptor.
36
37 = To-many relationships =
38
39 ERRest won't let you add or remove objects in a to-many relationship, it can only update an existing object that is in the relationship. To add a new object to a relationship, you first need to fetch (or create) the parent object and make a second call to create the object and add it to the relationship.
40
41 So let's say you have an existing Organization object and you want to add a Member to it. First, you need to fetch the Organization :
42
43 {{code}}
44
45 GET /cgi-bin/WebObjects/ra/Organization/1.json
46
47 {{/code}}
48
49 and after, you create a new Member :
50
51 {{code}}
52
53 POST /cgi-bin/WebObjects/ra/Organization/1/addMember.json
54
55 {{/code}}
56
57 = Same Origin policy =
58
59 If you are planning to offer your REST services to other people, they might run into Same Origin Policy problem. When using XMLHttpRequest on a page who is on a different domain than the REST service, XMLHttpRequest will tell you that it's not acceptable.
60
61 To get around that problem, many solutions has been found, but two of them are more accepted than the others : [[JSONP>>http://en.wikipedia.org/wiki/JSON#JSONP]] and [[HTTP//access//control>>https://developer.mozilla.org/en/HTTP_access_control]]. I didn't try the JSONP route, but I did try HTTP//access//control, and Dojo and Prototype are using this method to get around the Same Origin policy problem.
62
63 HTTP//access//control works by adding new headers in the request that says which HTTP methods the request wants to do, and it's send as a OPTIONS HTTP method. You MUST reply with some headers to this OPTIONS request. Support for those headers was added in ERRest somewhere in october 2010.
64
65 To enable the headers and support for the OPTIONS method, add this property:
66
67 {{code}}
68 ERXRest.accessControlAllowOrigin=*
69 {{/code}}
70
71 If you want to allow origin for only a specific host, change the value of the property to the IP or DNS name of the requester.
72
73 Now, sadly only newer (2008 or later) browsers support the HTTP Access Control standard. For older browsers, you have to support JSONP, or the [[window.name transport>>http://www.sitepen.com/blog/2008/07/22/windowname-transport/]]. JSONP is not integrated in JSONP, but you can use the window.name transport by enabling support with the following property.
74
75 {{code}}
76 ERXRest.allowWindowNameCrossDomainTransport=true
77 {{/code}}
78
79 == Dates ==
80
81 The default formatter for dates is :
82
83 {{code}}
84
85 %Y-%m-%dT%H:%M:%SZ
86
87 {{/code}}
88
89 If you want to work with the the GMT offset, you have to use this instead :
90
91 {{code}}
92
93 %Y-%m-%dT%H:%M:%S%z
94
95 {{/code}}
96
97 To change it, you have to set the "er.rest.timestampFormat" property :
98
99 {{code}}
100
101 er.rest.timestampFormat = %Y-%m-%dT%H:%M:%S%z
102
103 {{/code}}
104
105 If you are using Dojo, you can use dojo.date.stamp.toISOString and dojo.date.stamp.fromISOString to convert from or to a Java date object.
106
107 == JSON Schema support ==
108
109 ERRest have support for [[JSON Schema>>http://www.sitepen.com/blog/2008/10/31/json-schema/]] since october 2010. JSON Schema is like a mini-WSDL, where it describe which properties JSON objects have. Dojo use JSON Schema to perform client-side validation, which is cool because you can have some automatic validation based on your model, and validation is done even before the data is sent back to your REST service.
110
111 To get the schema, you need to check in your route action. For example, for the "index" action, you do:
112
113 {{code}}
114
115 public WOActionResults indexAction() throws Throwable {
116 if (isSchemaRequest()) {
117 return schemaResponse(yourERXKeyFilter());
118 }
119 ... do your normal work here
120 }
121
122 {{/code}}
123
124 And you call your REST route, but by adding "?schema=true" at the end of the URL. For example, ///ra/events.json?schema=true//. When you do that, a JSON Schema will be returned. Sample:
125
126 {{code}}
127
128 {
129 "name":"Event",
130 "properties":{
131 "isFullDay":{
132 "optional":true,
133 "type":"string",
134 "maxLength":5
135 },
136 "startDate":{
137 "optional":false,
138 "type":"string",
139 "format":"date-time"
140 },
141 "realDuration":{
142 "optional":true,
143 "type":"integer"
144 }
145 }
146 }
147
148 {{/code}}
149
150 So when you create a new Event with Dojo, if you try to put something else than a date in startDate, or you put a string in realDuration, it will fail because the schema says that startDate is using the date-time format, and that realDuration is a integer.