plone / plone.rest

Plone support for HTTP verbs (GET, POST, PUT, DELETE, ...)
https://pypi.org/project/plone.rest/
11 stars 5 forks source link

REST API calls not (always) working in ISiteRoot context #27

Closed zopyx closed 8 years ago

zopyx commented 8 years ago

I configured a service

<plone:service
   for="*"
   name="create"
   method="PUT"
/>

The service is supposed to work in the context of folderish objects including the Plone root. The service method is trigger for PUT against a Plone folder but does not trigger a call against the Plone site root.

lukasgraf commented 8 years ago

@zopyx could you elaborate on how exactly you're calling that service, and in what way it fails on the Plone site root?

The following works for me:

  <plone:service
     for="*"
     name="create"
     method="PUT"
     factory=".service.PutService"
  />
class PutService(Service):

    def render(self):
        return {'id': self.context.id}
lukasgraf@helios ~/src/plone.restapi $ http -j PUT http://localhost:8080/Plone/create
HTTP/1.1 200 OK
Content-Length: 19
Content-Type: application/json
Date: Fri, 11 Dec 2015 07:19:38 GMT
Server: Zope/(2.13.23, python 2.7.8, darwin) ZServer/1.1

{
    "id": "Plone"
}

lukasgraf@helios ~/src/plone.restapi $ http -j PUT http://localhost:8080/Plone/my-folder/create
HTTP/1.1 200 OK
Content-Length: 23
Content-Type: application/json
Date: Fri, 11 Dec 2015 07:19:40 GMT
Server: Zope/(2.13.23, python 2.7.8, darwin) ZServer/1.1

{
    "id": "my-folder"
}
zopyx commented 8 years ago

I have this PUT configuration here:

https://github.com/xml-director/xmldirector.crex/blob/master/xmldirector/crex/browser/configure.zcml#L36-L41

which is supposed to work against any resource.

It does not work against the Plone root (return a 204 response):

PUT http://dev1.veit-schiele.de:12020/Plone/xmldirector-create
<Response [204]>
[1] > /home/ajung/sandboxes/xmldirector.plonecore/src/xmldirector.crex/scripts/api-sample.py(78)<module>()
-> verify_result(result)
(Pdb++) result.text
u''
(Pdb++) result.content
''

but working against a folder

PUT http://dev1.veit-schiele.de:12020/Plone/folder/xmldirector-create
<Response [201]>
[1] > /home/ajung/sandboxes/xmldirector.plonecore/src/xmldirector.crex/scripts/api-sample.py(77)<module>()
-> verify_result(result)
(Pdb++) result
<Response [201]>
(Pdb++) result.text
u'{\n  "id": "c01d4eef-17e6-4f3b-bb34-1662985dfcb3", \n  "url": "http://dev1.veit-schiele.de:12020/Plone/folder/c01d4eef-17e6-4f3b-bb34-1662985dfcb3"\n}'
(Pdb++) result.json()
{u'url': u'http://dev1.veit-schiele.de:12020/Plone/folder/c01d4eef-17e6-4f3b-bb34-1662985dfcb3', u'id': u'c01d4eef-17e6-4f3b-bb34-1662985dfcb3'}

The service implemenation is here:

https://github.com/xml-director/xmldirector.crex/blob/master/xmldirector/crex/browser/service.py#L192-L225

The method is only entered for a folder context but not for the Plone root.

lukasgraf commented 8 years ago

Hmm. I can't see anything wrong with that service.

I'm curious where that 204 is being generated. We provide an adapter for error handling so that we can avoid the formatted HTML response and instead return a JSON response in a common format. Any exception that occurred will be passed to response.setStatus(), which will convert it to a numeric status code according to a mapping in ZPublisher.HTTPResponse. But I can't see any special handling for 204 there, so I suspect our error handler isn't even called.

Is the Content-Type of the response even application/json?

One possibility could be that you're hitting Zope's WebDav implementation, which we're trying to avoid in plone.rest. But that also doesn't quite add up, because WebDav PUT should be disallowed on the Plone site root and be answered with 405 (if you were to somehow hit the WebDav implementation).

zopyx commented 8 years ago

The headers are correct:

https://github.com/xml-director/xmldirector.crex/blob/master/scripts/api-sample.py#L20-L54

No idea about the 204 response. My API implementation sets the status code to 201 (CREATED) in case of success,

lukasgraf commented 8 years ago

Hmm, still can't reproduce it here with your api-sample.py script (with minor modifications) and a trivial service implementation on the server side. I notice you're testing quite a few other HTTP verbs - are you only experiencing this with PUT so far?

This is quite difficult for me to diagnose without being able to reproduce it. If I experienced this locally, I'd probably set a conditional PDB breakpoint in BaseRequest.traverseName():

if name == 'xmldirector-create':
    import pdb; pdb.set_trace()

In the working case, this should eventually lead to your service adapter being returned from this named adapter lookup.

BTW, which Plone version are you testing this with?

zopyx commented 8 years ago

hm...closing...can no longer reproduce this error with my test script and unittests.