On Mon, Nov 23, 2009 at 11:34 AM, Ross Vandegrift <[email protected]> wrote:
> Hi everyone,
>
> I'm adding API functionality to an exiting app whose controller
> actions aren't close to being in shape for direct exposure. This
> pretty much precludes me from turning them into REST controllers and
> accomplishing this task that way.
>
> So I've created a new api controller that will house the actions for
> programmatic access. This has an unfortunate side effect of making my
> routing kind of difficult.
>
> For example, suppose I have model objects X and Y and the following API:
>
> class ApiController(BaseController):
> �...@jsonify
> def getXbyid(self, id):
> q = meta.session.query(model.X)
> result = q.get(id)
> return {"result": result.__json__()}
>
> �...@jsonify
> def getXbyacct(self, acct):
> q = meta.session.query(model.X)
> result = q.filter_by(acct=acct).one()
> return {"result": result.__json__()}
>
> �...@jsonify
> def getYbyname(self, name):
> q = meta.session.query(model.Y)
> result = q.filter_by(name=name).one()
> return {"result": result.__json__()}
>
>
> How can I effectively map these actions without listing each action in
> my routes? The best I have come up with is to include a route for
> each parameter name I use:
>
> map.connect("/api/{action}/{id:[0-9]+}", controller="api")
> map.connect("/api/{action}/{acct:[0-9]+}", controller="api")
> map.connect("/api/{action}/{name:[a-zA-Z0-9+}", controller="api")
The answer is to use a generic 'id' variable in the route, and to
rename the variable in the action. This is the philosophy behind the
default "/{controller}/{action}/{id}" route.
map.connect("/api/{action}/{id}", controller="api")
#### Actions
def by_id(self, id):
id = self._get_int_id(id)
...
def by_acct(self, id):
acct = self._get_int_id(id)
...
def by_name(self, id):
name = self._get_alphanumeric_id(id)
...
#### Private methods, maybe in base controller
def _get_int_id(self, id, errmsg="Invalid numeric ID."):
try:
return int(id)
except ValueError:
abort(404, errmsg)
NAME_RX = re.compile(R"^[a-zA-Z0-9]+$")
def _get_alphanumeric_id(self, id, errmsg="ID may contain only letters
and digits."):
if not NAME_RX.match(id):
abort(404, errmsg)
return id
--
Mike Orr <[email protected]>
--
You received this message because you are subscribed to the Google Groups
"pylons-discuss" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/pylons-discuss?hl=.