Skip to content

Provide extensibility scenario for app namespace #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
hossam-nasr opened this issue Jan 30, 2023 · 4 comments
Open

Provide extensibility scenario for app namespace #55

hossam-nasr opened this issue Jan 30, 2023 · 4 comments

Comments

@hossam-nasr
Copy link
Contributor

hossam-nasr commented Jan 30, 2023

Related to #12. Currently, the app object provided from the root of the @azure/functions library (in v4), is a namespace:

import { app } from `@azure/functions`

app.get(/* function*/);

This provides limited extensibility when it comes to users/other packages adding their own methods to the root app namespace. For example, the Durable SDK had no easy way to add an app.durableOrchestration() method to register durable functions, and instead it has to export its own functions under its own namespace.

This issue is to discuss how/if we should provide a way for another package to extend the app namespace with their own methods. One such suggestion would be to make app an instance of a Class instead of an object, which can then be extended by other packages. Example:

import { FuncApp } from '@azure/functions'
import * as df from 'durable-functions';

let app = new FuncApp();
app = df.addDurableMagic(app);

app.get(/* HTTP function */); // same methods exist as before

app.durableOrchestration(/* Durable function */);  // external package can add its own methods too

Instead of using the new FuncApp() syntax, which may not be very idiomatic to node, we could also follow Express's model and export a function that does this behind the scenes. Example:

const func = require('@azure/functions');
const df = require('durable-functions');

let app = func();
app = df.addDurableMagic(app);

// same as before
app.get(/* */);
app.durableOrchestration(/* */);

There could be other ways of providing this extensibility too, but this is the easiest one I could think of 🙂

@hossam-nasr
Copy link
Contributor Author

cc @jviau

@aaronpowell
Copy link
Contributor

I had a chat with @ejizba on an internal thread about this as well, as being able to extend the app namespace would be useful for scenarios where you're trying to create an abstraction layer over the top of Functions. With app being a namespace type in the new model it's hard to something that extends the types.

@ejizba
Copy link
Contributor

ejizba commented Jan 31, 2023

I would like to see user feedback and other examples in the Node.js ecosystem before we spend time on this. I'm not convinced it's a problem or that the solutions suggested are idiomatic to Node.js.

My gut is telling me that people are used to having a lot of npm packages and would be fine with importing some stuff from @azure/functions and other stuff from durable-functions. In fact, I would argue users would be confused if a durable method was coming from @azure/functions or app.get was coming from durable-functions.

@aaronpowell
Copy link
Contributor

I wonder if a more approachable middleware option might fill the gap.

One of the projects I was experimenting with is my Open API extension (https://github.com/aaronpowell/azure-functions-nodejs-openapi) and how to register Open API against the endpoint(s) that you have.

My initial thought was to have an extension method on the .get so you could go app.get(...).openApi() but as it returns a void that was possible, so instead the idea was to go app.openApi('routeName', handler) but again, that's not really possible as you can't extend app.

Middleware might tackle this:

import { app } from "@azure/functions";
import { openApiMiddleware } from "...";

app.middleware(openApiMiddleware({ ... }), "http");

app.get(...);

the app.middleware function would take a middleware handler and an optional trigger type filter, so you can scope the usage of it.

Not sure if that'd improve durable's design though.

@ejizba ejizba added this to the Backlog Candidates milestone Apr 3, 2023
@ejizba ejizba added the hooks label Apr 3, 2023
@ejizba ejizba added P3 and removed v4 🚀 We no longer use this label since v4 is now the default model. labels Oct 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants