AppEnginge dispatch.yaml url - google-app-engine

I have this:
- url: "awesome.com/*"
service: awesome
- url: "www.awesome.com/*"
service: awesome
Is possible to do this? to achieve same as above?
- url: "*.awesome.com/*"
service: awesome

No, what that last option you mentioned would do is map all subdomains of awesome.com to the service awesome, as you can see in this example corresponding to mapping subdomains in the documentation.
Here you have more information about mapping custom domains.

Yes, it's possible to do that. But it won't be equivalent with what you have now:
it won't match your top-level domain awesome.com which is matched by your current 1st rule
it'll match any <blah>.awesome.com subdomain, your current set of rules only matches the www.awesome.com subdomain
If indeed you want to send requests for both the full domain as well as all its subdomains to the awesome service you can achieve that simply by the custom domain mapping/config itself (which you need to do explicitly for the domain and each subdomain anyways), no need for a dispatch file.
Note that you'd still need to deploy a default service, see Why do I need to deploy a "default" app before I can deploy multiple services in GAE?. Might as well just let the awesome service be the default one in this case, less confusing and less room for trouble IMHO.

Related

App Engine standard dispatch.yaml 20 rules limit

I am facing an issue with the 20 limit dispatch.yaml rule
Currently I am using "client".mydomain.com which is easy to setup
But I have some bigger clients who I want to put onto a separate service
My goal was the following,
Public website
Put 30-50 clients on service A using "client".mydomain.com
Put 1 client on service B using "client".mydomain.com
Put 20-30 clients on service C
But then using number 3 I need to be creative and use something like "client".2.mydomain.com. I would rather see also just "client".mydomain.com on service C
Now dispatch.yaml does have a 20 rule limit, so putting many clients on a separate service is not possible. Eventually I will run into the limit
Anyone has any ideas on to fix this, or do this in another way.
I am open for any suggestions, I was thinking of putting up an nginx, but not each service has it's own ip, so that also not a possibility. Perhaps some new features or so ?
I could also just setup different "similar" domain names and map those like mydomainapp.com appmydomain.com etc, but that would be a bit too much
Currently my dispatch.yaml looks like
dispatch:
- url: "domain.com/*"
service: default
- url: "www.domain.com/*"
service: default
- url: "*.domain.com/*"
service: myapp
- url: "*/something"
service: myapp
- url: "*/*"
service: default
So any ideas on how to make this working for everything so that I can use "client".domain.com for every
For better routing you can make use of a Load Balancer in front of your App Engine services, and add App Engine as a NEG (Network Endpoint Group).
If you set up the Load Balancer and the NEG, you can then create a URL Map or even URL Masks to determine which service should be handling the request.
With that option you'll be also removing the limit that you've encountered while using the dispatch.yaml file to define the routing paths.

Directing requests to instance on Google Cloud

Is it possible to group certain requests togeather based on their url ensuring that similar requests go to the same instance?
E.g.
There are multiple instances for my app engine
myurl.com?foo=abc // Multiple people putting in this url will all go to the same instance
myurl.com // I don't care which one this goes
I don't think you can control which instance handles a url pattern.
If you want to send certain urls to a certain service, what you want is a dispatch.yaml, which does exactly that. You can use regex to tailor how you want. With some strategy, you could match urls with (groups of) instances, though they would be in separate services. If your site doesn't get a lot of traffic, you could essentially have one instance per service, and accomplish what you want.
dispatch:
# don't forget: gcloud app deploy dispatch.yaml after changes !!!
- url: "*/some/high/memory/urls/*"
service: my_high_memory_service
- url: "*/some/fast/cpu/url"
service: my_fast_cpu_service
- url: "*/.*"
service: default
More at: https://cloud.google.com/appengine/docs/standard/python/reference/dispatch-yaml

Can I point a domain at a google app engine service?

I have two very simple services set up (in python) on google app engine. I have a site which has been up for a while as the defualt service of my example project, and I just deployed another service, lets call it foo. I have dns forwarding working for the default service, so I can go to example.com (which I own in this hypothetical scenario) and see my default service. I can also go to foo.example.appspot.com and see my foo service, which works at the url.
I have also registered another domain, let's call it foo.com. What I want is for foo.com to use my foo.example.appspot.com service. To make matters trickier, foo.com has a bunch of sub-domains of it's own, so I need x.foo.com to go to my foo service as well (and even x.y.foo.com would be ideal, but if that is hard I can work around that one easily enough by just substituting out another character so it would be x-y.foo.com or something along those lines).
I'm pretty new to web dev (which is honestly a generous description for this simple project), but Iv'e spent a while reading and googling and haven't found a solution to this, so any advice would be helpful. My last resort would be to un-service-ify (if you will) the two services, and just bundle it all up into one big main.py which routes differently depending on the domain, and then point both domains at the default service. The big downside to this is that I already have everything working with services (which seems like a better approach).
I expect to get very few users so scaling isn't really an issue (though it's always interesting to learn about).
EDIT:
attempted to create a dispatch.yaml file to solve this as follows:
dispatch:
- url: "foo.com"
module: foo
- url: "*.foo.com"
module: foo
but when I run appcfg.py -A <project_id_here> update_dispatch . it says
Error parsing yaml file:
Unable to assign value 'foo.com' to attribute 'url':
invalid url 'foo.com'
in "./dispatch.yaml", line 3, column 10
Yes, it should be possible. I didn't actually use 2 different top-level domains, but the development console appears to be ready to accept a second one (I can't actually check as I don't own a 2nd domain). Follow the Adding a custom domain for your application procedure.
Pay special attention to the Wildcard mappings section - since your foo.com domain already has sub-domains in use you can't use wildcards at/above those sub-domains, you'll have to specify the desired subdomains.
The procedure only maps (sub)domains to the app as a whole, not to individual services/modules. You'll also have to use a dispatch file, to route the specific subdomains to the corresponding modules/services. You can find examples here: https://stackoverflow.com/a/32103486/4495081 and https://stackoverflow.com/a/34111170/4495081 (the last one has rules to allow the module to work on the custom domain, on appspot.com and on the local development server).
I got it to work following The links in the answer. My dispatch file wound up looking like this:
dispatch:
- url: "foo.com/*"
module: foo
- url: "*.foo.com/*"
module: foo

Semantics of dispatch.yaml

I'm looking at various pages about dispatch.yaml, most of which contain similar information and examples:
https://cloud.google.com/appengine/docs/flexible/nodejs/how-requests-are-routed#routing_with_a_dispatch_file
https://cloud.google.com/appengine/docs/python/config/dispatchref
https://cloud.google.com/appengine/docs/go/config/dispatchref
etc.
I happen to be using node.js on GAE Flexible Environment, but I think it would be the same for every language and environment.
The problem is that these pages don't really specify how dispatch.yaml works. In particular:
Are rules applied in the order given? I'm assuming that the first matching rule is the one used, but nothing seems to say so.
Do leading glob (wildcard) characters match only the domain name, or could they match the first part of the URL's path? If the rule is */hello, would that match myapp.appspot.com/path/hello? I'm guessing not, based on some vague hints in the docs, but it isn't very clear.
If no rule in dispatch.yaml matches the URL, will it be routed to the default service? I would think it would have to, but again, these pages don't say.
Do URLs get rewritten based on the rules before they're sent to the service? If the rule is */path/* and the URL is https://myapp.appspot.com/path/hello, will the service see it as /path/hello or as /hello? I'm guessing the former.
I'm doing some trial and error now, so I may be able to answer my own question soon. I'm also submitting this to Google through their documentation feedback system.
Things I know so far:
Yes, rules are tried in order. So for example, if you want one URL to go to a specific service, and all other URLs to go to another service, you should specify the specific one first:
dispatch:
- url: "*/specific"
module: specific
- url: "*/*"
module: general
If you put those rules in the opposite order, module specific will never be used, because the URL /specific will be caught by the wildcard rule.
Unknown
Yes. You can test this by making a request not matching any dispatch.yaml rule and watching the default's service logs.
No rewriting. If the rule is */path/* and the actual URL is https://myapp.appspot.com/path/hello, your service should still handle /path/hello, not /hello.
Just to fill in the blank (feel free to paste this into the accepted answer):
No. It only matches the start of the path.
I created two apps with the following resources:
default -> /abc/def/test.html -> <h1>default</h1>
other -> /abc/def/test.html -> <h1>other</h1>
And 1 route:
<dispatch>
<url>*/def/*</url>
<module>other</module>
</dispatch>
When I hit {app engine}/abc/def/test.html I got "default"

How do i get foo.somedomain.com get handled by myapp.appspot.com/foo on appengine

Here is what I'd like to achieve
http://foo.somedomain.com gets handled by
http://myapp.appspot.com/foo (google appengine app myapp)
and the underlying url is masked.
Note the following:
somedomain.com is a third party domain that would like to add foo.somedomain.com
mydomain.com would be CNAME'd to myapp.appspot.com
mydomain.com/foo would point to myapp.appspot.com/foo
other scenarios
can foo.mydomain.com be made to point to myapp.appsot.com/foo
can foo.somedomain.com point directly to myapp.appspot.com/foo
Added: myapp.appspot.com is developed using django w/ app-engine-patch
You can't do this in the way described. In order to do this, you need to:
CNAME foo.somedomain.com to ghs.google.com (not to myapp.appspot.com)
Set up Google Apps for your Domain on somedomain.com, if it's not already
Add the app 'myapp' to foo.somedomain.com through the Apps control panel
Once that's done, your app can check self.request.host to determine which hostname was sent, and route requests appropriately.
You can parse the sub-domain from the Host header, then call the webapp.RequestHandler appropriate for the path /[sub-domain], assuming *.yourdomain.com is directed to the Google App Engine application.
Have a look at webapp.WSGIApplication and see if there's a way to get the mapped webapp.RequestHandler for a path. Alternatively, you might be able to modify the request object to change the requested path (this I'm not sure about, however.)
This question was asked in one of the 2009 Google I/O app engine talks. Unfortunately the answer given was along the lines of not supported at this time but the possibilities of some workarounds may exist. 2009 Google I/O videos

Resources