Appwrite: Add api gateway for custom business logic

Created on 1 Dec 2019  路  4Comments  路  Source: appwrite/appwrite

Right now you have to set up your own backend server to handle functionality that is not handled by Appwrite as a consequence your front end app should then talk to two backend services. Often the custom backend service will have to talk to Appwrite to check user sessions and other information.

To get around that complexity Appwrite should function as an api gateway for the custom backend service. Like it is possible to define tasks that call http endpoints it should be possible to create routes in Appwrite that forward the request to the custom backend service. For instance, a request to http://appwrite.io/{project id}/myservice/a_resource/1 should be routed to my backend service. Appwrite adds info about authenticated user and other relevant information in the header before calling the custom service. It should be possible as an option to tell Appwrite only route if user is authenticated.

This could also function as a kind of extension system for Appwrite if combined with the possibility to create custom scopes that could be applied to api keys.

I imagine the following gateway api:

appwrite.io/v1/gateway/services
get, returns all services
post, a custom backend service register itself to Appwrite. Parameters are service name, description and scope name.

appwrite.io/v1/gateway/services/{id}/routes
get, returns all routes for a service.
post, adds a route for the service, parameters are endpoint and if user should be authenticated.

All this should, of course, be baked into an Appwrite sdk class. In python it could look something like this.

from appwrite.services.backend import BackendService
from flask import Flask, request

app = Flask(__name__)
@app.route('/hello')
def hello():
    user = request.headers.get('x-appwrite-user')
    return 'Hello  ' + user

# service is upp and running register it at appwrite
@app.before_first_request
def register():
    client=Client()
    client.set_project('5dd99163dd886')
    client.set_key('{a long api key}')

    my_service = BackendService(Client)
    my_service.set_name = "My service"
    my_service.set_api_name = "my-service"
    my_service.set_description = "This is my custom service"
    my_service.set_scope_name = "myServiceScopeName"
    my_service.set_endpoint ="http://192.168.0.1:5000"

    # register service on appwrite server
    my_service.register()

   # register route, user should be authenticated
    my_service.register_route("/hello", true)

if __name__ == '__main__':
    app.run(debug = True, host = '0.0.0.0')

And appwrite.io/{projectid}/my-service/hello should return "Hello {user}"

discussion enhancement

All 4 comments

I think this is something that can fit quite well in our stack. It's a complicated feature but definitely doable.

By using Appwrite as the only backend entry point, developers can take advantage of Appwrite security.

We will also be able to integrate abuse control and rate-limiting for each new route that is behind the gateway and offer input validation. We can use custom X-Appwrite headers to pass the user scope or an API key to let custom backend interact with Appwrite services using one of our SDK's

We still need to think how to allow access to new routes from our SDKs, should we also think about caching (acting as a CDN) and will this perform well when custom services are not on the same private network.

Just found Kong an api gateway that seems to handle "our" needs :-)

Kong

Indeed this would be a very useful addition to Appwrite; +1

This should now be available using Appwrite Cloud Functions: https://appwrite.io/docs/functions

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vincentnacar02 picture vincentnacar02  路  6Comments

Asored-D picture Asored-D  路  3Comments

FOUADFAISAL picture FOUADFAISAL  路  5Comments

mgkimsal picture mgkimsal  路  3Comments

mysticaltech picture mysticaltech  路  3Comments