Changes for page ERRest In Depth
Last modified by Pascal Robert on 2012/06/10 16:01
From version 40.1
edited by Pascal Robert
on 2012/05/02 21:50
on 2012/05/02 21:50
Change comment:
There is no comment for this version
To version 46.1
edited by Pascal Robert
on 2012/06/10 16:01
on 2012/06/10 16:01
Change comment:
Migrated to Confluence 4.0
Summary
-
Page properties (1 modified, 0 added, 0 removed)
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,6 +46,7 @@ 46 46 ** er.rest.timestampFormat.secondary 47 47 ** er.rest.timestampFormatter 48 48 ** er.rest.rfcDateFormat 191 +** er.rest.jodaTime 49 49 ** ERXRest.transactionsEnabled (default 'false') ERXRestTransactionRequestAdaptor 50 50 ** ERXRest.maxEventsPerTransaction (default '50') ERXRestTransactionRequestAdaptor 51 51 ** ERXRest.accessControlAllowRequestHeaders (ERXRouteController) ... ... @@ -54,11 +54,14 @@ 54 54 *** (default "xml") Allow you to set the default format for all of your REST controllers 55 55 ** ERXRest.allowWindowNameCrossDomainTransport (ERXRouteController) 56 56 ** ERXRest.accessControlMaxAge (ERXRouteController) 57 -*** (default 1728000) This header indicates how long the results of a preflight request can be cached. 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. 58 58 ** ERXRest.accessControlAllowOrigin (ERXRouteController) 59 -*** Set the value to '* *' to enable all origins. See https:~/~/developer.mozilla.org/En/HTTP_access_control#Access-Control-Allow-Origin**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"]] 60 60 * JSON Schema 61 -** {{code}} 204 +** 205 + 206 +{{code}} 207 + 62 62 /something?schema=true 63 63 64 64 public WOActionResults indexAction() { ... ... @@ -68,71 +68,66 @@ 68 68 protected boolean isSchemaRequest() { 69 69 return request().stringFormValueForKey("schema") != null; 70 70 } 217 + 71 71 {{/code}} 72 72 73 -Same Origin policy 74 -Transactions 75 -HTML vs other formats 76 -Response representation 77 -Missing route 78 -Missing object 79 -POJO objects 80 -Headers 81 -Caching 82 -Adding new format 83 -Security 84 -strictMode 85 -Workflow 86 -Query arguments and RXRestFetchSpecification 87 -ERXRestNameRegistry 88 -MapClassDescription / NSDictionaryClassDescription 89 - 90 -ERXRestUtils 91 -Properties 92 -er.rest.dateFormat 93 -er.rest.timestampFormat 94 -er.rest.rfcDateFormat 95 - 96 -request > route 97 - 98 98 Application(ERXApplication).dispatchRequest(WORequest) line: 2051 99 -ERXRouteRequestHandler(WOActionRequestHandler). //handleRequest(WORequest) line: 221100 -ERXRouteRequestHandler.getRequestHandlerPathForRequest(WORequest) line: 782 //221 + ERXRouteRequestHandler(WOActionRequestHandler)._handleRequest(WORequest) line: 221 222 + ERXRouteRequestHandler.getRequestHandlerPathForRequest(WORequest) line: 782 101 101 102 -ERXRouteRequestHandler(WOActionRequestHandler). //handleRequest(WORequest) line: 259103 -PagesController(ERXRouteController).performActionNamed(String) line: 1328 104 -PagesController(ERXRouteController).performActionNamed(String, boolean) line: 1385 105 -PagesController(ERXRouteController).performRouteActionNamed(String) line: 1510 106 -PagesController(ERXRouteController).performActionWithArguments(Method, Object...) line: 1559 107 -... 108 -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 109 109 110 110 == ERXRouteRequestHandler == 111 111 112 -| **Properties** 113 -| ERXRest.missingControllerName | (default "ERXMissingRouteController") 114 -\\ 115 -| ERXRest.parseUnknownExtensions | ERXRest.parseUnknownExtensions 116 -\\ 117 -| ERXRest.pluralEntityNames | ERXRest.pluralEntityNames 118 -\\ 119 -| ERXRest.routeCase | ERXRest.routeCase 120 -\\ 121 -| 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 +))) 122 122 123 123 ERXMissingRouteController is the controller that is used when no route can be found. It's "missing" action is loaded. 124 124 125 -| **Properties** 126 -| ERXRest.strictMode | ERXRest.strictMode 127 -\\ | 128 -ERXRouteController 129 - 130 -Properties 131 - 132 -ERXRest.accessControlAllowRequestHeaders 133 -ERXRest.accessControlAllowRequestMethods 134 -ERXRest.defaultFormat 269 +|((( 270 +**Properties** 271 +))) 272 +|((( 135 135 ERXRest.strictMode 136 -ERXRest.allowWindowNameCrossDomainTransport 137 -ERXRest.accessControlMaxAge 138 -ERXRest.accessControlAllowOrigin 274 +)))|((( 275 +ERXRest.strictMode 276 + 277 +))) 278 + 279 +ERXRouteController