Extracting route variables directly from the request object in Play2/Scala - regex

The only part of the Request class that I have found to contain relevant information is the request.tags map, specifically the ROUTE_PATTERN value. For example, in a route such as /api/admin/:org/list the route pattern is /api/admin/$org<[^/]+>/list. Is there a way to match request.path against this pattern and retrieve the "org" variable (and any other path variables)? Or any other way to retrieve this variable for that matter -- but, again: directly from the request object.
Please note that this needs to be generic; for instance, the route could have two parameters, or more, and the proposed method should be able to find all those when searched for.

Related

How to pass a parameter date to url dispatcher but as named parameter

I've been reading lots of tutorials and stackoverflow questions, but I haven't found how to do this. I need to pass a parameter of type Date in a GET call on the URL.
I know it sounds easy, but I'm new to Django and what I have found is mostly something like this:
Django url that captures yyyy-mm-dd date
All those answers solve the issue if I want to have an URL like
http:www.myweb.com/2021/09/02
That is great if I want to write an url for a blog or website, but I'm doing it for an endpoint, and in my case, I need something like this
/some-action-endpoint/?created_at_gte=2020-01-01
So, I need to capture a parameter (hopefully named created_at_gte) with the value 2020-02-01 (It will awesome if I could capture that immediately as a Date object, but I'm fine with a string)
So, my questions are:
1.- It will be enough to create a group like this
url(r'^my-endpoint/(?P<created_at_gte>[(\d{2})[/.-](\d{2})[/.-](\d{4})]{4})/$', views.my_view),
Note_: by the way, the previous one is not working, if someone knows why it'll greatly appreciate it.
2.-The endpoint needs two parameters: created_at_gte and created_at_lte. How can I handle this? Do I need to add two url's to the url pattern?
I'm using Django 1.11 and Python 2.7. Cannot use other versions.
Query parameters aren't part of the URL matching behavior, so unfortunately your requirement to handle them as query parameters instead of URL path elements means you have to do more on your own rather than relying on pattern matching to reject bad requests.
You can do what you want as long as your base URL pattern (^my-endpoint/ in your example) is unambiguous and you're willing to handle the possibility that the parameters may not be set or may be set to something that doesn't parse as a date in your view, but you won't get the regexp-derived guarantees or the ability to bind them to view function parameters.
Instead, you'll have to extract them from the request.GET QueryDict object. That would look something like this:
In your url patterns:
url(r'^my-endpoint/$', views.my_view),
And then in your views:
def my_view(request):
created_at_start = request.GET.get("created_at_gte")
created_at_end = request.GET.get("created_at_lte")
# you now have no guarantees about these values except that if not None they'll be strings
# remember to do something appropriate for None, empty strings, strings that aren't dates, strings where end is before the start, etc

Coldbox routing dynamic number of path variables

I am working on a coldbox application where I would like to create a route that accepts 'n' number of path variables as one variable. Here is what I mean.
http://localhost/api/variable1/variable2/variable3/...
I would like to either be able to grab everything after /api as one path variable where I can split on / and get the values or be able to iterate over all variables after /api.
Is there a way to setup a Route to do this?
with(pattern="/api", handler="api")
.addRoute(pattern="/:variables", action="index")
.endWith();
Any ideas would be most appreciated. Thanks in advance.
As you probably know, the default routing paradigm is to do name value pairs like so:
http://localhost/api/name1/value1/name2/value2/name3/value3
There is no need to create a custom route for that as everything after the matched part of the route is broken up into name/value pairs and placed in the rc automatically.
Now, it sounds like you're wanting to only have values in your route. If you know the maximum number of variables you'll ever have, you could create a route of optional, incrementally-named variables.
addRoute(pattern="/:var1?/:var2?/:var3?/:var4?/:var5?", action="index")
Now, if you truly might have an unlimited number of variables, there is no way to do a route that will match that. What you CAN do is have your route match the /api bit and write an onRequestCapture interceptor that grabs the URL and does your own custom parsing on it. Note, you may need to remove the name/value pairs that ColdBox will try to put in the rc.
I will add a note of caution-- the only way for this to really work is for you to KNOW the order of the incoming variables ahead of time, and if you know that, there is no reason why you can't create a known route for it. Otherwise you're basically rebuilding the SES interceptor over again which is an anti-pattern called "inner platform effect"
http://wiki.coldbox.org/wiki/URLMappings.cfm#URL_Mappings
http://wiki.coldbox.org/wiki/Interceptors.cfm#Core_Interception_Points
http://en.wikipedia.org/wiki/Inner-platform_effect

Django reverse routing - solution to case where reverse routing is less specific than forward routing

I have a route defined as follows:
(r'^edit/(\d+)/$', 'app.path.edit')
I want to use the reverse function as follows:
url = reverse('app.path.edit', args=('-id-',))
The generated url gets passed to a js function, and client side code will eventually replace '-id-' with the correct numeric id. This of course won't work, because the 'reverse' function won't match the route, because the url is defined as containing a numeric argument.
I can change the route to accept any type of argument as follows, but then I loose some specificity:
(r'^edit/(.+)/$', 'app.path.edit'
I could create a separate url for each item being displayed, but I'll be displaying many items in a list, so it seems like a waste of bandwidth to include the full url for each item.
Is there a better strategy to accomplish what I want to do?
You can rewrite regexp like this:
(r'^edit/(\d+|-id-)/$', 'app.path.edit')
but I generally prefer this:
(r'^edit/([^/]+)/$', 'app.path.edit') # you can still differ "edit/11/" and "edit/11/param/"
Usually you will anyway need to check entity for existent with get_object_or_404 shortcut or similar, so the only bad is that you have to be more accurate with incoming data as id can contain almost any characters.
In my opinion, and easier solution would be to keep the original url and then pass the value '0' instead of '-id-'. In the client side then you replace '/0/' with the correct id. I think this is better because it doesn't obscure the url routing, and you don't lose specificity.

How to solve two REST problems: the interface document; loss of privacy in descriptive URLs

Coming from a lot of frustrating times with WSDL/Soap, I very much like the REST paradigm, but am trying to solve two basic problems in our application, before moving over to REST. The first problem relates to the lack of an interface document. I think I finally see how to handle this situation: One can query his way down from a top-level "/resources" resource using various requests of GET, HEAD, and OPTIONS to find the one needed resource in the correct hypermedia format. Is this the idea? If so, the client need only be provided with a top-level resource URI: http://www.mywebservicesite.com/mywebservice/resources. He will then have to do some searching and possible keep track of what he is discovering, so that he can use the URIs again efficiently in future to do GETs, POSTs, PUTs, and DELETEs. Are there any thoughts on what should happen here?
The other problem is that we cannot use descriptive URLs like /resources/../customer/Madonna/phonenumber. We do have an implementation of opaque URLs we use in the context of a session, and I'm wondering how opaque URLs might be applied to REST. The general problem is how to keep domain-specific details out of URLs, and still benefit from what REST has to offer.
The other problem is that we cannot use descriptive URLs like /resources/../customer/Madonna/phonenumber.
I think you've misunderstood the point of opaque URIs. The notion of opaque URIs is with respect to clients: A client shall not decipher a URI to guess anything of semantic meaning from it. So a service may well have URIs like /resources/.../customer/Madonna/phonenumber, and that's quite a good idea. The URIs should be treated as opaque by clients: not infer from the URI that it represents Madonna's phone number, and that Madonna is a customer of some sort. That knowledge can only be obtained by looking inside the URI itself, or perhaps by remembering where the URI was discovered.
Edit:
A consequence of this is that navigation should happen by links, not by deconstructing the URI. So if you see /resouces/customer/Madonna/phonenumber (and it actually represents Customer Madonna's phone number) you should have links in that resource to point to the Madonna resource: e.g.
{
"phone_number" : "01-234-56",
"customer_URI": "/resources/customer/Madonna"
}
That's the only way to navigate from a phone number resource to a customer resource. An important aspect is that the server implementation might or might not have domain specific information in the URI, The Madonna record might just as well live somewhere else: /resources/customers/byid/81496237. This is why clients should treat URIs as opaque.
Edit 2:
Another question you have (in the comments) is then how a client, with the required no knowledge of the server's URIs is supposed to be able to find anything. Clients have the following possibilities to find resources:
Provide a search interface. This could be done by providing an OpenSearch description document, which tells clients how to search for items. An OpenSearch template can include several variables, and several endpoints, depending on what you're looking for. So if you have a "customer ID" that's unique, you could have the following template: /customers/byid/{proprietary:customerid}", the customerid element needs to be documented somewhere, inside the proprietary namespace. A client can then know how to use such a template.
Provide a custom form. This implies making a custom media type in which you explicitly define how (based on an instance of the document) a URI to a customer can be forged. <customers template="/customers/byid/{id}"/>. The documentation (for the media type) would have to state that the template attribute must be interpreted as a relative URI after the string substitution "{id}" to an actual customer ID.
Provide links to all resources. Some resources aren't innumerable, so you can simply make a link to each and every one of them, optionally including identifying information along with the links. This could also be done in a custom media type: <customer id="12345" href="/customer/byid/12345"/>.
It should be noted that #1 and #2 are two ways of saying the same thing: Clients are allowed to create URIs if they
haven't got the URI structure a priori
a media type exists for which the documentation states that URIs should be created
This is much the same way as a web browser has no idea of any URI structure on the web, except for the rules laid out in the definition of HTML forms, to add a ? and then all the query parameters separated by &.
In theory, if you have a customer with id 12345, then you could actually dispense with the href, since you could plug the customer id 12345 into #1 or #2. It's more common to actually provide real links between resources, rather than always relying on lookup or search techniques.
I haven't really used web RPC systems (WSDL/Soap), but i think the 'interface document' is there mostly to allow client libraries to create the service API, right? if so, REST shouldn't need it, because the verbs are already defined and don't really need to be documented again.
AFAIUI, the REST way is to document the structure of each resource (usually encoded in XML or JSON). In that document, you'll also have to document the relationship between those resources. In my case, a resource is often a container of other resources (sometimes more than one type), therefore the structure doc specifies what field holds a list of URLs pointing to the contained resources. Ideally, only one unique resource will need a single, fixed (documented) URL. everithing else follows from there.
The URL 'style' is meaningless to the client, since it shouldn't 'construct' an URL. Every URL it needs should be already constructed on a resource field. That let's you change the URL structure without changing the client (that has saved tons of time to me). Your URLs can be as opaque or as descriptive as you like. (personally, i don't like text keys or slugs; my keys are all BIGINTs or UUIDs)
I am currently building a REST "agent" that addresses the first part of your question. The agent offers a temporary bookmarking service. The client code that is interacting with the agent can request that an URL be bookmarked using some identifier. If the client code needs to retrieve that representation again, it simply asks the agent for the url that corresponds to the saved bookmark and then navigates to that bookmark. Currently those bookmarks are not persisted so they only last for the lifetime of the client application, but I have found it a useful mechanism for accessing commonly used resources. E.g. The root representation provides a login link. I bookmark that link and if the client ever receives a 401 then I can redirect to the "login" bookmark.
To address an issue you mentioned in a comment, the agent also has the ability to store retrieved representations in a dictionary. If it becomes necessary to aggregate and manipulate multiple representations at the same time then I can simply request that the agent store the current representation in a dictionary associated to a key and then continue navigating to the next resource. Once the client has accumulated all the necessary representation it can do what it needs to do.

How do I add a prefix to all urls and generically parse that as a kwarg

Let's say I have a site where all urls are username specific.
For example /username1/points/list is a list of that user's points.
How do I grab the /username1/ portion of the url from all urls and add it as a kwarg for all views?
Alternatively, it would be great to grab the /username1/ portion and append that to the request as request.view_user.
You might consider attacking this with middlware. Specifically using process_request. This is called before the urlresolver is called and you can do pretty much anything to the request (request.path in this case) you want to. You might strip out the username and store it in the request object. Specifics depend (obviously) on the conditions under which you do/do not want to remove the first path component.
Updated for comment:
Whichever way you go about it, when you call reverse() you have to give it the additional context info -- it can't just automagically figure it out for itself. Django doesn't play any man-behind-the-curtains games -- everything is straight Python and there isn't any global state floating around just off stage. I think this is a Good Thing™.