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
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
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,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: 22191 -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: 25994 -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