Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

All OPTIONs permutations can't be supported #313

Closed
CodeOtter opened this Issue · 7 comments

4 participants

@CodeOtter

Some time ago, I added the OPTIONS annotation to make the bundle more HTTP compliant, but it revealed a new issue :X

If this is my controller:

/**
 * @Prefix("api")
 * @NamePrefix("EDDM_CampaignApi_")
 */
class UserController extends Controller {
    public function getUserAction($id) {...}
    public function postUserAction() {...}
    public function putUserAction($id) {...}
    public function deleteUserAction($id) {...}
    public function getUsersAction() {...}
    public function patchUserAction($id) {...}
    public function optionUserAction() {...}
    public function optionUsersAction() {...}
}

I get the following routes:

GET http://www.site.com/api/users/{id}
POST http://www.site.com/api/user
PUT http://www.site.com/api/users/{id}
DELETE http://www.site.com/api/users/{id}
GET http://www.site.com/api/users
PATCH http://www.site.com/api/users/{id}
OPTIONS http://www.site.com/api/users/{id}
OPTIONS http://www.site.com/api/users

But I have no way of defining a method that allows for this:

OPTIONS http://www.site.com/api/user

This means if I request OPTIONS http://www.site.com/api/users/{id} or OPTIONS http://www.site.com/api/users, I can never get back Allow: POST in the headers, which means any true REST client will not discover a way to create records via this API.

Even if you use RouteResource or ClassResourceInterface, you end up with these methods:

public function optionUsersAction($id) {...}
public function coptionUserAction() {...}
public function coptionUsersAction() {...}

The c prefix does not apply to OPTIONS, and if two methods create the same route, then the last defined one takes precedence.

@stof
Owner

The POST route should be pointing to api/users, not to api/user

@CodeOtter

I agree, it should be. Sadly, in 0.9.0, it does not.

php app/console router:debug | grep POST
Project_UserApi_post_user                          POST    /api/user.{_format}
@CodeOtter

Even in the event of a plural naming convention being adopted everywhere, you still encounter the problem where if you wanted to do an OPTION on the collection vs. an OPTION on a resource:

OPTIONS http://www.site.com/api/users/{id}
OPTIONS http://www.site.com/api/users

How would that even look in a REST Controller? o_____O

public function optionsUserAction() {...}
public function optionsUserAction($id) {...}

That'll cause an error. And I really doubt that you'd like it if a single Action qualified as two routes via:

public function optionsUserAction($id = null) {...}
@Nercury

Function names can be different for different route matching patterns.

@lsmith77
Owner

ok finally got some time to look at this in details.

first up postUserAction should be written as postUsersAction since you are posting to the users collection. for putUserAction i guess the idea is that you are putting a single user. not sure if this is logical but this is how it is atm ..

now with the following code:

/**
 * @Prefix("api")
 * @NamePrefix("EDDM_CampaignApi_")
 */
class UserController extends Controller
{
    public function getUserAction($id) {}
    public function postUsersAction() {}
    public function putUserAction($id) {}
    public function deleteUserAction($id) {}
    public function getUsersAction() {}
    public function patchUserAction($id) {}
    public function optionsUserAction($id) {}
    public function optionsUsersAction() {}
}

i get these routes:

EDDM_CampaignApi_delete_user      DELETE  /api/users/{id}.{_format}
EDDM_CampaignApi_get_user         GET     /api/users/{id}.{_format}
EDDM_CampaignApi_get_users        GET     /api/users.{_format}
EDDM_CampaignApi_options_user     OPTIONS /api/users/{id}.{_format}
EDDM_CampaignApi_options_users    OPTIONS /api/users.{_format}
EDDM_CampaignApi_patch_user       PATCH   /api/users/{id}.{_format}
EDDM_CampaignApi_post_users       POST    /api/users.{_format}
EDDM_CampaignApi_put_user         PUT     /api/users/{id}.{_format}

isnt this what you want?

@lsmith77
Owner

oh and using http://symfony-standard.lo/app_dev.php/api/users.json with a POST/OPTIONS request gives me GET, OPTIONS, POST for the Allow response header

@lsmith77
Owner

closing .. please reopen if i did not properly analyze the issue.

@lsmith77 lsmith77 closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.