Le 2011-03-30 à 13:33, Andrew Kinnie a écrit :
> Yes, I should have remembered that about query parameters I suppose. Though
> it's been a while.
>
> I would still prefer doing it via REST, because that is what they asked me to
> provide as an interface. However, as I just found out no one here actually
> knows anything about REST my motivation is waning.
>
> So, for those keeping score, I do now know how to pass in the string as a
> variable, but currently, with this action method:
>
> public WOActionResults fetchByNameAction() {
> String typeName = routeObjectForKey("name");
> NotificationType type =
> NotificationType.fetchNotificationType(editingContext(),
> NotificationType.TYPE_NAME.eq(typeName));
> return response(type, showFilter());
> }
>
> Registered this way:
>
> routeRequestHandler.addRoute(new
> ERXRoute(NotificationType.ENTITY_NAME, "/NotificationType/{name:String}",
> ERXRoute.Method.Get, NotificationTypeController.class, "fetchByName"));
>
> I get this exception:
>
> Mar 30 13:21:33 MyApp[9001] ERROR er.rest.routes.ERXRouteController -
> Request failed:
> /cgi-bin/WebObjects/MyApp.woa/ra/NotificationType/alert/fetchByName.json
If you want to call your URL like this, you have to rework your route to be
like this:
new ERXRoute(NotificationType.ENTITY_NAME,
"/NotificationType/{name:String}/fetchByName"
> ValidationException: Error encountered converting value of class
> java.lang.String to type specified in attribute 'notificationTypeId' of
> entity 'NotificationType'
> at com.webobjects.eoaccess.EOAttribute.validateValue(EOAttribute.java:2572)
> at
> er.rest.ERXEORestDelegate._fetchObjectOfEntityWithID(ERXEORestDelegate.java:89)
> at
> er.rest.ERXAbstractRestDelegate.objectOfEntityWithID(ERXAbstractRestDelegate.java:96)
> at er.rest.ERXRestUtils.coerceValueToTypeNamed(ERXRestUtils.java:258)
> at er.rest.routes.ERXRoute.keysWithObjects(ERXRoute.java:370)
> at
> er.rest.routes.ERXRouteController.routeObjects(ERXRouteController.java:348)
> at
> er.rest.routes.ERXRouteController.routeObjectForKey(ERXRouteController.java:327)
> at
> com.MyApp.controllers.NotificationTypeController.fetchByNameAction(NotificationTypeController.java:114)
> ... skipped 4 stack elements
> at
> er.rest.routes.ERXRouteController.performActionNamed(ERXRouteController.java:1368)
> at
> er.rest.routes.ERXRouteController.performActionNamed(ERXRouteController.java:1234)
> ... skipped 8 stack elements
>
> At this point, I may just require the client to get the list, get the object
> (if one exists) for the DeviceNotificationType pointing to the device and the
> notification type, and create one if it doesn't exist.
>
> I thought I should be able to do all that easily in WO.
>
>
> On Mar 30, 2011, at 11:46 AM, Pascal Robert wrote:
>
>>
>> Le 2011-03-30 à 11:42, Andrew Kinnie a écrit :
>>
>>> OK, dumb question, how would I do that here?
>>
>> To use query params, use the good old request().XXXXFormValueForKey methods.
>> Example:
>>
>> public WOActionResults loginAction() {
>> String username = this.request().stringFormValueForKey("username");
>> String password = this.request().stringFormValueForKey("password");
>> User user = User.fetchUser(editingContext(),
>> User.USERNAME.eq(username).and(User.PASSWORD.eq(password)));
>> if (user == null) {
>> throw new SecurityException();
>> }
>> session().setCurrentUser(user);
>> return response(user, ERXKeyFilter.filterWithNone());
>> }
>>
>>
>>> (sorry the deadline is looming, and I don't generally have to think in
>>> terms of what the url the client needs use to get the proper results. I've
>>> not even done much with direct actions)
>>
>> Stateless Web make more sense to me :-)
>>
>>>
>>> On Mar 30, 2011, at 11:34 AM, David LeBer wrote:
>>>
>>>>
>>>> On 2011-03-30, at 11:28 AM, Mike Schrag wrote:
>>>>
>>>>> you can also just use regular query parameters if you really want ... to
>>>>> hell with purists.
>>>>
>>>> +1 :-)
>>>>
>>>>>
>>>>> ms
>>>>>
>>>>> On Mar 30, 2011, at 11:21 AM, Andrew Kinnie wrote:
>>>>>
>>>>>> OK. I'm now in a bit of time crunch, so I just want to get something
>>>>>> working.
>>>>>>
>>>>>> assuming I have a route
>>>>>>
>>>>>> new ERXRoute(NoteType.ENTITY_NAME, "/NoteType/{name:String}",
>>>>>> ERXRoute.Method.Get, NoteTypeController.class, "fetchByName")
>>>>>>
>>>>>> What is the url I need to actually pass in a string using this
>>>>>> fetchByNameAction?
>>>>>>
>>>>>> If I do /ra/NotificationType/fetchByName I get 0 objects (because name
>>>>>> == null)
>>>>>>
>>>>>> How do I pass in a string? What is the url I need to use for this?
>>>>>> (every rest tutorial I have looked at either doesn't apply at all, or
>>>>>> doesn't help)
>>>>>>
>>>>>> Thanks
>>>>>>
>>>>>> On Mar 30, 2011, at 11:12 AM, Mike Schrag wrote:
>>>>>>
>>>>>>> admittedly i've only sort of half-read this thread, but i would think
>>>>>>> you could make a custom NodeTypeRestDelegate that has your own
>>>>>>> implementation of createObjectOfID that checks to see if there already
>>>>>>> is one and just returns it ... maybe. there are a bunch of ways you can
>>>>>>> do things by hooking into those delegates. you can also probably do
>>>>>>> some tricks by using key filter delegates.
>>>>>>>
>>>>>>> ms
>>>>>>>
>>>>>>> On Mar 30, 2011, at 10:58 AM, Andrew Kinnie wrote:
>>>>>>>
>>>>>>>> Sorry about all this, Pascal. Didn't mean to make you write your
>>>>>>>> session early. :-) I guess I'm just dense about this stuff, never
>>>>>>>> having used Rest before, ERRest in particular, or, for that matter,
>>>>>>>> ever had to deal directly with HTTP response codes. This seems to
>>>>>>>> suggest that you can't, from within a controller for a given entity
>>>>>>>> (in this case "Device"), create a method with, based on a passed in
>>>>>>>> String, fetch an object of a different entity ("DeviceNoteType") which
>>>>>>>> points to (via a to-one) a NoteType object with the name passed in as
>>>>>>>> a variable?
>>>>>>>>
>>>>>>>> Basically I want to do this:
>>>>>>>> - create a single action method (in my DeviceController) which allows
>>>>>>>> the client to pass in a String variable "noteTypeName", then
>>>>>>>> - uses that String to fetch a DeviceNoteType object where the noteType
>>>>>>>> has that noteTypeName, and the device is the current device
>>>>>>>> --> If there is, set the status to active,
>>>>>>>> --> if not, create a new DeviceNoteType
>>>>>>>>
>>>>>>>> The issue I am having is that the passed in string ("noteTypeName") is
>>>>>>>> not a key on Device, but is rather used for fetching a different
>>>>>>>> object of a different entity. I am always getting null from the
>>>>>>>> routeObjectForKey method.
>>>>>>>>
>>>>>>>> I would really rather not have the client make two requests, and have
>>>>>>>> to figure out http return calls. I'd rather have them be able to
>>>>>>>> simply call the addNoteType action and pass in a typeName (and
>>>>>>>> eventually, be able to do this with an array of typeNames)
>>>>>>>>
>>>>>>>> __________________________________________
>>>>>>>>
>>>>>>>> I am willing to make the client call several action methods via curl
>>>>>>>> if needed.
>>>>>>>>
>>>>>>>> In any event, I don't seem to know how to actually call the route you
>>>>>>>> mentioned in your post. In my Application class I added the route:
>>>>>>>>
>>>>>>>> routeRequestHandler.addRoute(new
>>>>>>>> ERXRoute(NoteType.ENTITY_NAME, "/NoteType/{name:String}",
>>>>>>>> ERXRoute.Method.Get, NoteTypeController.class, "fetchByName"));
>>>>>>>>
>>>>>>>> Thing is, I have no idea at all how to call this from the command line
>>>>>>>> to see if it returns anything. (and I have no idea how the http
>>>>>>>> response codes would appear)
>>>>>>>>
>>>>>>>> I tried:
>>>>>>>>
>>>>>>>> curl -X GET
>>>>>>>> http://MacBook-Pro.local:9001/cgi-bin/WebObjects/ra/NoteType/[name='alert'].json
>>>>>>>> (curl: (3) [globbing] error: bad range specification after pos 80)
>>>>>>>> curl -X GET
>>>>>>>> http://MacBook-Pro.local:9001/cgi-bin/WebObjects/ra/NoteType/'alert'.json
>>>>>>>> (- Unable to get contents of file
>>>>>>>> '/Library/WebServer/Documents/cgi-bin/WebObjects/ra/NoteType/alert.json'
>>>>>>>> for uri: /cgi-bin/WebObjects/ra/NoteType/alert.json)
>>>>>>>> curl -X GET
>>>>>>>> http://MacBook-Pro.local:9001/cgi-bin/WebObjects/ra/NoteType/'alert'
>>>>>>>> (no alertAction method)
>>>>>>>>
>>>>>>>> And various other things. I've tried to find rest tutorials to
>>>>>>>> indicate what the syntax is supposed to be, but everything seems to be
>>>>>>>> assuming you're passing in an id, which, obviously, I don't have.
>>>>>>>>
>>>>>>>> Assuming I eventually get this basic bit of syntax down, it looks like
>>>>>>>> the client would need to call the create on the DeviceNoteType and
>>>>>>>> pass in fully formed json representations of the NoteType and the
>>>>>>>> Device? Presumably they would do this by getting the json from the
>>>>>>>> response?
>>>>>>>>
>>>>>>>> Sorry for not getting this stuff.
>>>>>>>>
>>>>>>>> Andrew
>>>>>>>>
>>>>>>>>
>>>>>>>> On Mar 29, 2011, at 4:21 PM, Pascal Robert wrote:
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Le 2011-03-29 à 16:03, Andrew Kinnie a écrit :
>>>>>>>>>
>>>>>>>>>> Thanks for the tip on using create that way. I didn't know you
>>>>>>>>>> could do that. In any event, that's the problem. NoteType is
>>>>>>>>>> basically a lookup table. I would want to fetch an existing
>>>>>>>>>> noteType based on some unique attribute, such as "typeName" (which
>>>>>>>>>> ensure is unique in the EO class) I don't want to create a new
>>>>>>>>>> noteType, I want to create the intervening object (DeviceNoteType)
>>>>>>>>>> which has a to-one to NoteType and a to-one to Device. AND (here's
>>>>>>>>>> the tough part - for me at least) I want to only create a new one if
>>>>>>>>>> one doesn't already exist. So I need to fetch first, and I want to
>>>>>>>>>> fetch based on the value passed in for the name key
>>>>>>>>>
>>>>>>>>> So you will do:
>>>>>>>>>
>>>>>>>>> new ERXRoute(NoteType.ENTITY_NAME, "/NoteType/{name:String}",
>>>>>>>>> ERXRoute.Method.Get, NoteTypesController.class, "fetchByName");
>>>>>>>>>
>>>>>>>>> public WOActionResults fetchByNameAction() {
>>>>>>>>> String typeName = routeObjectForKey("name");
>>>>>>>>> NoteType type = NoteType.fetchNoteType(editingContext(),
>>>>>>>>> User.NAME.eq(typeName));
>>>>>>>>> return response(type, yourerxkeyfilter());
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> If fetchByNameAction didn't find an object, ERRest will return the
>>>>>>>>> HTTP code 404, so your client can know that the object was not found,
>>>>>>>>> and call:
>>>>>>>>>
>>>>>>>>> new ERXRoute(NoteType.ENTITY_NAME, "/NoteType/",
>>>>>>>>> ERXRoute.Method.Post, NoteTypesController.class, "create"); // If
>>>>>>>>> you called addDefaultRoutes for the NoteType entity, that route
>>>>>>>>> already exist)
>>>>>>>>>
>>>>>>>>> public WOActionResults createAction() {
>>>>>>>>> NoteType type = create(NoteType.ENTITY_NAME, yourerxkeyfilter());
>>>>>>>>> editingContext().saveChanges();
>>>>>>>>> return response(type, yourerxkeyfilter());
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> If you get a response with HTTP code in the 20x range, the object was
>>>>>>>>> created and now you can create your DeviceNoteType with a route like
>>>>>>>>> this:
>>>>>>>>>
>>>>>>>>> new ERXRoute(DeviceNoteType.ENTITY_NAME, "/DeviceNoteType",
>>>>>>>>> ERXRoute.Method.Post, DeviceNoteTypesController.class, "create");
>>>>>>>>>
>>>>>>>>> When you call POST /cgi-bin/WebObjects/MyApp.woa/ra/DeviceNoteType,
>>>>>>>>> you will have to pass the a Device and a NoteType object in JSON as
>>>>>>>>> the body of the request.
>>>>>>>>>
>>>>>>>>> I feel like I'm writing my WOWODC session in real-time :-P
>>>>>>>> _______________________________________________
>>>>>>>> Do not post admin requests to the list. They will be ignored.
>>>>>>>> Webobjects-dev mailing list ([email protected])
>>>>>>>> Help/Unsubscribe/Update your Subscription:
>>>>>>>> http://lists.apple.com/mailman/options/webobjects-dev/mschrag%40pobox.com
>>>>>>>>
>>>>>>>> This email sent to [email protected]
>>>>>>>
>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Do not post admin requests to the list. They will be ignored.
>>>>> Webobjects-dev mailing list ([email protected])
>>>>> Help/Unsubscribe/Update your Subscription:
>>>>> http://lists.apple.com/mailman/options/webobjects-dev/dleber_wodev%40codeferous.com
>>>>>
>>>>> This email sent to [email protected]
>>>>
>>>> ;david
>>>>
>>>> --
>>>> David LeBer
>>>> Codeferous Software
>>>> 'co-def-er-ous' adj. Literally 'code-bearing'
>>>> site: http://codeferous.com
>>>> blog: http://davidleber.net
>>>> profile: http://www.linkedin.com/in/davidleber
>>>> twitter: http://twitter.com/rebeld
>>>> --
>>>> Toronto Area Cocoa / WebObjects developers group:
>>>> http://tacow.org
>>>>
>>>>
>>>>
>>>>
>>>
>>> _______________________________________________
>>> Do not post admin requests to the list. They will be ignored.
>>> Webobjects-dev mailing list ([email protected])
>>> Help/Unsubscribe/Update your Subscription:
>>> http://lists.apple.com/mailman/options/webobjects-dev/probert%40macti.ca
>>>
>>> This email sent to [email protected]
>>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com
This email sent to [email protected]