Changes for page ERRest In Depth

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

From version 5.1
edited by Pascal Robert
on 2012/03/11 21:14
Change comment: There is no comment for this version
To version 16.1
edited by Pascal Robert
on 2012/06/10 15:33
Change comment: There is no comment for this version

Summary

Details

Page properties
Content
... ... @@ -1,6 +1,6 @@
1 -RestContext
2 -Properties
3 -JSON Schema
1 +General architecture
2 +Same Origin policy
3 +Transactions
4 4  HTML vs other formats
5 5  Response representation
6 6  Missing route
... ... @@ -8,9 +8,170 @@
8 8  POJO objects
9 9  Headers
10 10  Caching
11 +Adding new format
12 +Security
13 +strictMode
14 +Workflow
15 +Query arguments and RXRestFetchSpecification
16 +ERXRestNameRegistry
17 +MapClassDescription / NSDictionaryClassDescription
11 11  
19 +Calling an action goes like this:
20 +
21 +{{code}}
22 +
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 +
38 +if (transactionAdaptor.transactionsEnabled() && !transactionAdaptor.isExecutingTransaction(context(), request())) {
39 + if (!transactionAdaptor.willHandleRequest(context(), request())) {
40 + if (transactionAdaptor.didHandleRequest(context(), request())) {
41 + results = stringResponse("Transaction request enqueued.");
42 + } else {
43 + results = stringResponse("Transaction executed.");
44 + }
45 + }
46 +}
47 +
48 +if (results == null) {
49 + checkAccess();
50 +}
51 +
52 +if (results == null && isAutomaticHtmlRoutingEnabled() && format() == ERXRestFormat.html()) {
53 + results = performHtmlActionNamed(actionName);
54 +}
55 +
56 +if (results == null) {
57 + results = performRouteActionNamed(actionName);
58 +}
59 +
60 +if (results == null) {
61 + results = response(null, ERXKeyFilter.filterWithAttributes());
62 +}
63 +else if (results instanceof IERXRouteComponent) {
64 + _takeRouteParametersFromRequest(results);
65 +}
66 +
67 +{{/code}}
68 +
69 +checkAccess:
70 +
71 +{{code}}
72 +
73 +protected void checkAccess() throws SecurityException {
74 +}
75 +
76 +{{/code}}
77 +
78 +ERXRestUtils
79 +
12 12  request > route
13 13  
82 +{{code}}
83 +
84 +/**
85 + * A NameFormat that behaves like Rails -- plural entities, plural routes, lowercase underscore names
86 + * (names_like_this).
87 + */
88 + public static NameFormat RAILS = new NameFormat(true, true, NameFormat.Case.LowercaseUnderscore);
89 +
90 + /**
91 + * A NameFormat that behaves like WO -- singular entities, singular routes, camel names (NamesLikeThis).
92 + */
93 + public static NameFormat WO = new NameFormat(false, false, NameFormat.Case.CamelCase);
94 +
95 + /**
96 + * A NameFormat that behaves like WO -- singular entities, singular routes, lowercase camel names (namesLikeThis).
97 + */
98 + public static NameFormat WO_LOWER = new NameFormat(false, false, NameFormat.Case.LowerCamelCase);
99 +
100 +{{/code}}
101 +
102 +* ERXRestContext
103 +** contains the editing context and an userInfo dictionnary
104 +** will be populated with er.rest.dateFormat, er.rest.timestampFormatter and er.rest.timestampFormat (read only for non-HTML responses)
105 +*** want to change the time format for a specific controller?
106 +
107 +{{code}}
108 +
109 +protected ERXRestContext createRestContext() {
110 + ERXRestContext restContext = new ERXRestContext(editingContext());
111 + restContext.setUserInfoForKey("yyyy-MM-dd", "er.rest.dateFormat");
112 + restContext.setUserInfoForKey("yyyy-MM-dd", "er.rest.timestampFormat");
113 + return restContext;
114 + }
115 +
116 +{{/code}}
117 +
118 +*
119 +** you just need to override createRestContext() in your controller if you want to add other stuff to the context (a user, etc.)
120 +* Properties
121 +** ERXRest.idKey (ERXRestFormatDelegate)
122 +*** (default "id") Override this property if you want to use a different key for the 'id' attribute** ERXRest.typeKey**
123 +** ERXRest.nilKey (ERXRestFormatDelegate)
124 +** ERXRest.writeNilKey (ERXRestFormatDelegate)
125 +** ERXRest.pluralEntityNames (ERXRestFormatDelegate)
126 +** ERXRest.writeTypeKey (ERXRestFormatDelegate)
127 +** ERXRest.suppressTypeAttributesForSimpleTypes (ERXXmlRestWriter)
128 +*** (default "false") If set to true, primitive types, like type = "datetime", won't be added to the output
129 +** ERXRest.strictMode
130 +*** In ERXMissingRouteController: (default "true") If set to true, status code in the response will be 405 Not Allowed, if set to false, status code will be 404 Not Found
131 +*** In ERXRouteController: (default "true") If set to true, status code in the response will be 405 Not Allowed, if set to false, status code will be 404 Not Found
132 +*** ERXRouteResults: (default "true") If set to true, creating a ressource will return status code 201 Created, if set to false, will return 200 OK
133 +** ERXRest.pluralEntityNames (ERXRouteRequestHandler)
134 +** ERXRest.routeCase (ERXRouteRequestHandler)
135 +** ERXRest.lowercaseEntityNames (ERXRouteRequestHandler)
136 +** ERXRest.parseUnknownExtensions (ERXRouteRequestHandler)
137 +*** (default "true") If set to "false", will return a 404 status code if the format doesn't exist
138 +** ERXRest.missingControllerName (ERXRouteRequestHandler)
139 +*** (default "ERXMissingRouteController") Allow you to specify which controller to use when a route doesn't exist
140 +** er.rest.rfcDateFormat
141 +** er.rest.dateFormat
142 +** er.rest.dateFormat.primary
143 +** er.rest.dateFormat.secondary
144 +** er.rest.dateFormatter
145 +** er.rest.timestampFormat
146 +** er.rest.timestampFormat.primary
147 +** er.rest.timestampFormat.secondary
148 +** er.rest.timestampFormatter
149 +** er.rest.rfcDateFormat
150 +** er.rest.jodaTime
151 +** ERXRest.transactionsEnabled (default 'false') ERXRestTransactionRequestAdaptor
152 +** ERXRest.maxEventsPerTransaction (default '50') ERXRestTransactionRequestAdaptor
153 +** ERXRest.accessControlAllowRequestHeaders (ERXRouteController)
154 +** ERXRest.accessControlAllowRequestMethods (ERXRouteController)
155 +** ERXRest.defaultFormat (ERXRouteController)
156 +*** (default "xml") Allow you to set the default format for all of your REST controllers
157 +** ERXRest.allowWindowNameCrossDomainTransport (ERXRouteController)
158 +** ERXRest.accessControlMaxAge (ERXRouteController)
159 +*** (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.
160 +** ERXRest.accessControlAllowOrigin (ERXRouteController)
161 +*** Set the value to '**' to enable all origins. See [[https://developer.mozilla.org/En/HTTP_access_control#Access-Control-Allow-Origin]]**
162 +* JSON Schema
163 +** {{code}}
164 +/something?schema=true
165 +
166 +public WOActionResults indexAction() {
167 +if (isSchemaRequest()) {
168 + return schemaResponse(showFilter());
169 +}
170 +protected boolean isSchemaRequest() {
171 + return request().stringFormValueForKey("schema") != null;
172 +}
173 +{{/code}}
174 +
14 14  Application(ERXApplication).dispatchRequest(WORequest) line: 2051
15 15  ERXRouteRequestHandler(WOActionRequestHandler).//handleRequest(WORequest) line: 221
16 16  ERXRouteRequestHandler.getRequestHandlerPathForRequest(WORequest) line: 782//
... ... @@ -42,13 +42,3 @@
42 42  | ERXRest.strictMode | ERXRest.strictMode
43 43  \\          |
44 44  ERXRouteController
45 -
46 -Properties
47 -
48 -ERXRest.accessControlAllowRequestHeaders
49 -ERXRest.accessControlAllowRequestMethods
50 -ERXRest.defaultFormat
51 -ERXRest.strictMode
52 -ERXRest.allowWindowNameCrossDomainTransport
53 -ERXRest.accessControlMaxAge
54 -ERXRest.accessControlAllowOrigin