Possible to have multiple languages in a single application with routing?

Issue

You can use multiple services in Google App Engine and each service can be in its own language. This is usually done by having different url prefixes, so for example one url is:

  • myapp.com/js/*
  • myapp.com/python/*

However, I’m wondering if you can mix-and-match endpoints and just set them up with a dispatch file. Here is what I have so far to give an idea of what I’m trying to do:

  • default-multi/
    • app.yaml
    • dispatch.yaml
    • js/
      • js.yaml
      • package.json
      • server.js
    • py/
      • py.yaml
      • requirements.txt
      • main.py

And the files are:

js/js.yaml

runtime: nodejs14
service: js

js/package.json

{
  "engines": {
    "node": "14.x"
  },
  "dependencies": {
    "express": "^4.17.1"
  }
}

js/server.js

'use strict';
const express = require('express');
const app = express();
app.get('/js', (req, res) => {
  res.status(200).send('Hello, world!').end();
});

app.listen(8080, () => {});
module.exports = app;

py/requirements.txt

Flask==2.1.3

py/py.yaml

runtime: python39
service: py

py/main.py

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/py')
def hello():
    return jsonify(hello='world')

app.yaml

runtime: python39 # requires I add this ?
service: default

dispatch.yaml

dispatch:
  - url: "*/py$"
    service: py

  - url: "*/js$"
    service: js

And to dispatch:

$ gcloud app deploy app.yaml js/js.yaml py/py.yaml dispatch.yaml

Is there an actual way to accomplish what I’m trying to do above, or is it just not possible using GAE?

Solution

This is possible. Here is a working example I have now:

  • default_multi/
    • dispatch.yaml

      dispatch:
        - url: "*/js"
          service: js
        - url: "*/py"
          service: default # 'py'
      
    • js/

      • js.yaml

        runtime: nodejs14
        service: js
        
      • package.json

        {
          "engines": {
              "node": "14.x"
          },
          "dependencies": {
              "express": "^4.17.1"
          }
        }
        
      • server.js

        'use strict';
        const express = require('express');
        const app = express();
        app.get('/js', (req, res) => {
           res.status(200).send('Hello, world!').end();
        });
        
        app.listen(8080, () => {});
        module.exports = app;
        
    • py/

      • py.yaml

        # set this as 'default' yaml
        runtime: python39
        service: default
        
      • requirements.txt

        Flask==2.1.3
        
      • main.py

        from flask import Flask, jsonify
        
        app = Flask(__name__)
        @app.route('/py')
        def hello():
           return jsonify(hello='world')
        

And the command to run it:

$ gcloud app deploy py/py.yaml js/js.yaml dispatch.yaml

The main points here are that:

  • One server needs to be registered as the default service, even if the packages are split and equivalent in priority.
  • Only the dispatch.yaml goes at the top level. This acts as the service-router now.

Answered By – David542

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published