Changes for page ERRest In Depth

Last modified by Pascal Robert on 2012/06/10 16:01

From version 44.1
edited by Pascal Robert
on 2012/05/02 21:09
Change comment: There is no comment for this version
To version 46.1
edited by Pascal Robert
on 2012/06/10 16:01
Change comment: Migrated to Confluence 4.0

Summary

Details

Page properties
Content
... ... @@ -1,10 +1,156 @@
1 -* ERXRestContext
2 -** contains the editing context and an userInfo dictionnary
3 -** will be populated with er.rest.dateFormat, er.rest.timestampFormatter and er.rest.timestampFormat (read only for non-HTML responses)
4 -*** want to change the time format for a specific controller?
1 +General architecture
2 + Same Origin policy
3 + Transactions
4 + HTML vs other formats
5 + Response representation
6 + Missing route
7 + Missing object
8 + POJO objects
9 + Headers
10 + Caching
11 + Adding new format
12 + Security
13 + strictMode
14 + Workflow
15 + Query arguments and RXRestFetchSpecification
16 + ERXRestNameRegistry
17 + MapClassDescription / NSDictionaryClassDescription
5 5  
19 +Calling an action goes like this:
20 +
6 6  {{code}}
7 7  
23 +Application.dispatchRequest ->
24 +ERXRouteRequestHandler.handleRequest ->
25 +ERXRouteRequestHandler._handleRequest ->
26 +RestEntitiesController(ERXRouteController).performActionNamed(String actionName, false throwExceptions) ->
27 +RestEntitiesController(ERXRouteController).performRouteActionNamed -> RestEntitiesController(ERXRouteController).performActionWithArguments(Method, Object...) ->
28 +Method.invoke -> ...
29 +RestEntitiesController.indexAction()
30 +
31 +{{/code}}
32 +
33 +performActionNamed:
34 +
35 +{{code}}
36 +
37 +if (transactionAdaptor.transactionsEnabled() && !transactionAdaptor.isExecutingTransaction(context(), request())) {
38 + if (!transactionAdaptor.willHandleRequest(context(), request())) {
39 + if (transactionAdaptor.didHandleRequest(context(), request())) {
40 + results = stringResponse("Transaction request enqueued.");
41 + } else {
42 + results = stringResponse("Transaction executed.");
43 + }
44 + }
45 +}
46 +
47 +if (results == null) {
48 + checkAccess();
49 +}
50 +
51 +if (results == null && isAutomaticHtmlRoutingEnabled() && format() == ERXRestFormat.html()) {
52 + results = performHtmlActionNamed(actionName);
53 +}
54 +
55 +if (results == null) {
56 + results = performRouteActionNamed(actionName);
57 +}
58 +
59 +if (results == null) {
60 + results = response(null, ERXKeyFilter.filterWithAttributes());
61 +}
62 +else if (results instanceof IERXRouteComponent) {
63 + _takeRouteParametersFromRequest(results);
64 +}
65 +
66 +{{/code}}
67 +
68 +ERXRouteController.checkAccess()
69 +
70 +Will do nothing by default. Override it to check for security.
71 +
72 +{{code}}
73 +
74 +protected void checkAccess() throws SecurityException {
75 +}
76 +
77 +{{/code}}
78 +
79 +ERXRouteController.performHtmlActionNamed
80 +
81 +{{code}}
82 + protected WOActionResults performHtmlActionNamed(String actionName) throws Exception {
83 + WOActionResults results = null;
84 +
85 + String pageName = pageNameForAction(actionName);
86 + if (_NSUtilities.classWithName(pageName) != null) {
87 + try {
88 + results = pageWithName(pageName);
89 + if (!(results instanceof IERXRouteComponent)) {
90 + log.error(pageName + " does not implement IERXRouteComponent, so it will be ignored.");
91 + results = null;
92 + }
93 + }
94 + catch (WOPageNotFoundException e) {
95 + log.info(pageName + " does not exist, falling back to route controller.");
96 + results = null;
97 + }
98 + }
99 + else {
100 + log.info(pageName + " does not exist, falling back to route controller.");
101 + }
102 +
103 + if (results == null && shouldFailOnMissingHtmlPage()) {
104 + results = performUnknownAction(actionName);
105 + }
106 +
107 + return results;
108 + }
109 +{{/code}}
110 +
111 +{{code}}
112 + protected String pageNameForAction(String actionName) {
113 + return entityName() + ERXStringUtilities.capitalize(actionName) + "Page";
114 + }
115 +{{/code}}
116 +
117 +{{code}}
118 +
119 + protected boolean shouldFailOnMissingHtmlPage() {
120 + return false;
121 + }
122 +
123 +{{/code}}
124 +
125 +ERXRestUtils
126 +
127 +request -> route
128 +
129 +{{code}}
130 +
131 +/**
132 + * A NameFormat that behaves like Rails -- plural entities, plural routes, lowercase underscore names
133 + * (names_like_this).
134 + */
135 + public static NameFormat RAILS = new NameFormat(true, true, NameFormat.Case.LowercaseUnderscore);
136 +
137 + /**
138 + * A NameFormat that behaves like WO -- singular entities, singular routes, camel names (NamesLikeThis).
139 + */
140 + public static NameFormat WO = new NameFormat(false, false, NameFormat.Case.CamelCase);
141 +
142 + /**
143 + * A NameFormat that behaves like WO -- singular entities, singular routes, lowercase camel names (namesLikeThis).
144 + */
145 + public static NameFormat WO_LOWER = new NameFormat(false, false, NameFormat.Case.LowerCamelCase);
146 +
147 +{{/code}}
148 +
149 +* ERXRestContext
150 +** contains the editing context and an userInfo dictionnary
151 +** will be populated with er.rest.dateFormat, er.rest.timestampFormatter and er.rest.timestampFormat (read only for non-HTML responses)
152 +*** want to change the time format for a specific controller?
153 +** {{code}}
8 8  protected ERXRestContext createRestContext() {
9 9   ERXRestContext restContext = new ERXRestContext(editingContext());
10 10   restContext.setUserInfoForKey("yyyy-MM-dd", "er.rest.dateFormat");
... ... @@ -11,14 +11,10 @@
11 11   restContext.setUserInfoForKey("yyyy-MM-dd", "er.rest.timestampFormat");
12 12   return restContext;
13 13   }
14 -
15 -{{/code}}
16 -
17 -*
18 -** you just need to override createRestContext() in your controller if you want to add other stuff to the context (a user, etc.)
160 +{{/code}}you just need to override createRestContext() in your controller if you want to add other stuff to the context (a user, etc.)
19 19  * Properties
20 20  ** ERXRest.idKey (ERXRestFormatDelegate)
21 -*** (default "id") Override this property if you want to use a different key for the 'id' attribute** ERXRest.typeKey**
163 +*** (default "id") Override this property if you want to use a different key for the 'id' attribute~*~* ERXRest.typeKey
22 22  ** ERXRest.nilKey (ERXRestFormatDelegate)
23 23  ** ERXRest.writeNilKey (ERXRestFormatDelegate)
24 24  ** ERXRest.pluralEntityNames (ERXRestFormatDelegate)
... ... @@ -46,10 +46,23 @@
46 46  ** er.rest.timestampFormat.secondary
47 47  ** er.rest.timestampFormatter
48 48  ** er.rest.rfcDateFormat
49 -** ERXRest.transactionsEnabled
50 -** ERXRest.maxEventsPerTransaction
191 +** er.rest.jodaTime
192 +** ERXRest.transactionsEnabled (default 'false') ERXRestTransactionRequestAdaptor
193 +** ERXRest.maxEventsPerTransaction (default '50') ERXRestTransactionRequestAdaptor
194 +** ERXRest.accessControlAllowRequestHeaders (ERXRouteController)
195 +** ERXRest.accessControlAllowRequestMethods (ERXRouteController)
196 +** ERXRest.defaultFormat (ERXRouteController)
197 +*** (default "xml") Allow you to set the default format for all of your REST controllers
198 +** ERXRest.allowWindowNameCrossDomainTransport (ERXRouteController)
199 +** ERXRest.accessControlMaxAge (ERXRouteController)
200 +*** (default 1728000) This header indicates how long the results of a preflight request can be cached. For an example of a preflight request, see the above examples.
201 +** ERXRest.accessControlAllowOrigin (ERXRouteController)
202 +*** Set the value to '*' to enable all origins. See [[https:~~/~~/developer.mozilla.org/En/HTTP_access_control#Access-Control-Allow-Origin>>url:https://developer.mozilla.org/En/HTTP_access_control#Access-Control-Allow-Origin||shape="rect"]]
51 51  * JSON Schema
52 -** {{code}}
204 +**
205 +
206 +{{code}}
207 +
53 53  /something?schema=true
54 54  
55 55  public WOActionResults indexAction() {
... ... @@ -59,71 +59,66 @@
59 59  protected boolean isSchemaRequest() {
60 60   return request().stringFormValueForKey("schema") != null;
61 61  }
217 +
62 62  {{/code}}
63 63  
64 -Same Origin policy
65 -Transactions
66 -HTML vs other formats
67 -Response representation
68 -Missing route
69 -Missing object
70 -POJO objects
71 -Headers
72 -Caching
73 -Adding new format
74 -Security
75 -strictMode
76 -Workflow
77 -Query arguments and RXRestFetchSpecification
78 -ERXRestNameRegistry
79 -MapClassDescription / NSDictionaryClassDescription
80 -
81 -ERXRestUtils
82 -Properties
83 -er.rest.dateFormat
84 -er.rest.timestampFormat
85 -er.rest.rfcDateFormat
86 -
87 -request > route
88 -
89 89  Application(ERXApplication).dispatchRequest(WORequest) line: 2051
90 -ERXRouteRequestHandler(WOActionRequestHandler).//handleRequest(WORequest) line: 221
91 -ERXRouteRequestHandler.getRequestHandlerPathForRequest(WORequest) line: 782//
221 + ERXRouteRequestHandler(WOActionRequestHandler)._handleRequest(WORequest) line: 221
222 + ERXRouteRequestHandler.getRequestHandlerPathForRequest(WORequest) line: 782
92 92  
93 -ERXRouteRequestHandler(WOActionRequestHandler).//handleRequest(WORequest) line: 259
94 -PagesController(ERXRouteController).performActionNamed(String) line: 1328
95 -PagesController(ERXRouteController).performActionNamed(String, boolean) line: 1385
96 -PagesController(ERXRouteController).performRouteActionNamed(String) line: 1510
97 -PagesController(ERXRouteController).performActionWithArguments(Method, Object...) line: 1559
98 -...
99 -PagesController.mainPageAction() line: 20//
224 +ERXRouteRequestHandler(WOActionRequestHandler)._handleRequest(WORequest) line: 259
225 + PagesController(ERXRouteController).performActionNamed(String) line: 1328
226 + PagesController(ERXRouteController).performActionNamed(String, boolean) line: 1385
227 + PagesController(ERXRouteController).performRouteActionNamed(String) line: 1510
228 + PagesController(ERXRouteController).performActionWithArguments(Method, Object...) line: 1559
229 + ...
230 + PagesController.mainPageAction() line: 20
100 100  
101 101  == ERXRouteRequestHandler ==
102 102  
103 -| **Properties**
104 -| ERXRest.missingControllerName | (default "ERXMissingRouteController")
105 -\\          
106 -| ERXRest.parseUnknownExtensions | ERXRest.parseUnknownExtensions
107 -\\          
108 -| ERXRest.pluralEntityNames | ERXRest.pluralEntityNames
109 -\\          
110 -| ERXRest.routeCase | ERXRest.routeCase
111 -\\          
112 -| ERXRest.lowercaseEntityNames | ERXRest.lowercaseEntityNames
234 +|(((
235 +**Properties**
236 +)))
237 +|(((
238 +ERXRest.missingControllerName
239 +)))|(((
240 +(default "ERXMissingRouteController")
241 +
242 +)))
243 +|(((
244 +ERXRest.parseUnknownExtensions
245 +)))|(((
246 +ERXRest.parseUnknownExtensions
247 +
248 +)))
249 +|(((
250 +ERXRest.pluralEntityNames
251 +)))|(((
252 +ERXRest.pluralEntityNames
253 +
254 +)))
255 +|(((
256 +ERXRest.routeCase
257 +)))|(((
258 +ERXRest.routeCase
259 +
260 +)))
261 +|(((
262 +ERXRest.lowercaseEntityNames
263 +)))|(((
264 +ERXRest.lowercaseEntityNames
265 +)))
113 113  
114 114  ERXMissingRouteController is the controller that is used when no route can be found. It's "missing" action is loaded.
115 115  
116 -| **Properties**
117 -| ERXRest.strictMode | ERXRest.strictMode
118 -\\          |
119 -ERXRouteController
120 -
121 -Properties
122 -
123 -ERXRest.accessControlAllowRequestHeaders
124 -ERXRest.accessControlAllowRequestMethods
125 -ERXRest.defaultFormat
269 +|(((
270 +**Properties**
271 +)))
272 +|(((
126 126  ERXRest.strictMode
127 -ERXRest.allowWindowNameCrossDomainTransport
128 -ERXRest.accessControlMaxAge
129 -ERXRest.accessControlAllowOrigin
274 +)))|(((
275 +ERXRest.strictMode
276 +
277 +)))
278 +
279 +ERXRouteController