MicrosoftDocs / azure-docs

Open source documentation of Microsoft Azure
https://docs.microsoft.com/azure
Creative Commons Attribution 4.0 International
10.29k stars 21.48k forks source link

What parts of the trigger are available for other input bindings? #118247

Closed oadrian2 closed 6 months ago

oadrian2 commented 11 months ago

I'm trying to figure out what values are populated for use in other kinds of binding. E.g., in SignalR, invocation arguments are available for binding, but I'm not seeing an equivalent here. triggerMetadata seems to be empty in the SWA-compatible WebPubSubContext version meaning we can't tie event-messages to other inputs and outputs (e.g., CosmosDB). And based on the lack of documentation of binding information, I imagine they're unavailable even in the WebPubSubTrigger version.


Document Details

Do not edit this section. It is required for learn.microsoft.com ➟ GitHub issue linking.

ManoharLakkoju-MSFT commented 11 months ago

@oadrian2 Thanks for your feedback! We will investigate and update as appropriate.

AjayKumar-MSFT commented 11 months ago

Your feedback has been shared with the content owner for further review. Thanks again for the feedback!

JialinXin commented 10 months ago

@oadrian2 I'm not quite understand your question. SWA only support HttpTrigger, that's why Web PubSub has a WebPubSubContext to deserialize the Web PubSub service http request to Web PubSub protocol input object. What do you mean by tie event message to CosmosDB input? Why you need to make it a CosmosDB input when the request is actually from Web PubSub service?

oadrian2 commented 10 months ago

I'm referring to cosmos DB inputs rather than triggers. Basically a way of a database query based on the event that was triggering of the web pub/sub similar to how you would with an HTTP request. With SignalR triggers, the parameters on the invocation can be mapped to cosmos DB bindings on the input which allows you to retrieve the data without having to actually invoke the client yourself.

JialinXin commented 10 months ago

Sorry I still couldn't get your idea. Would you share a sample code, maybe SignalR one that meet your ask?

oadrian2 commented 10 months ago

This is the doing a pseudo-patch operation, which is invoked through a SignalR trigger. Non-relevant code has been omitted. Let me know if you want further clarification on anything. Thank you for taking the time.

const updateTokenInput = input.cosmosDB({
  databaseName: DATABASE_NAME,
  collectionName: TOKENS_CONTAINER,
  connectionStringSetting: 'CosmosDBConnection',
  id: '{token.id}', // using token triggerMetadata (see below)
  partitionKey: '{mapId.game}', // using mapId triggerMetadata (see below)
});

//
app.generic('updateToken', {
  trigger: trigger.generic({
    type: 'signalRTrigger',
    hubName: 'map',
    category: 'messages',
    event: 'updateToken',
    // parameter names here will bind the arguments of the invoke to trigger bindings usable by inputs/outputs
    parameterNames: ['mapId', 'token'], 
  }),
  extraInputs: [updateTokenInput],
  extraOutputs: [signalRMessagesOutput, tokenContainerOutput],
  handler: async (_request, context) => {
    const mapId = context.triggerMetadata!.mapId as { id: string; game: string }; // id coming from patch request
    const token = context.triggerMetadata!.token as Token`; // patch data

    const { id: map, game } = mapId;
    const documentIn = (context.extraInputs.get(updateTokenInput) || {}) as object;
    const documentOut = { ...documentIn, ...token };

    context.extraOutputs.set(tokenContainerOutput, documentOut);
    context.extraOutputs.set(signalRMessagesOutput, [
      {
        target: 'tokenUpdated', // event name
        arguments: [mapId, documentOut], // arguments to event
      },
    ]);
  },
});
JialinXin commented 10 months ago

When work with WebPubSubTrigger, triggerMetadata is all the metadata pre-bind with it, where you can refer to section https://learn.microsoft.com/en-us/azure/azure-web-pubsub/reference-functions-bindings?tabs=csharp#usages about available items under different requests.

Example: image

I'm working on a chat sample under v4 model. And probably would help you easier get started.

JialinXin commented 10 months ago

You can refer to this chat sample: https://github.com/JialinXin/azure-webpubsub/tree/jixin/v4-js/samples/functions/js/simplechat_v4

oadrian2 commented 10 months ago

When work with WebPubSubTrigger, triggerMetadata is all the metadata pre-bind with it, where you can refer to section https://learn.microsoft.com/en-us/azure/azure-web-pubsub/reference-functions-bindings?tabs=csharp#usages about available items under different requests.

Example: image

I'm working on a chat sample under v4 model. And probably would help you easier get started.

What about in the SWA-style HTTP triggers?

JialinXin commented 10 months ago

Then you need to work with WebPubSubContext input binding and in the function, you can get the values by context.extraInputs.get('wpsContext'). And inner structure is described here: https://learn.microsoft.com/en-us/azure/azure-web-pubsub/reference-functions-bindings?tabs=csharp#webpubsubcontext-1

For example:

const wpsContext= input.generic({
    type: 'webPubSubContext',
    name: 'wpsContext',
    hub: 'sample_funcchatv4'
});

app.http('message', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    extraInputs: [wpsContext],
    handler: async (request, context) => {
        let wpsRequest = context.extraInputs.get('wpsContext').request;
        let data = request.data;
        ....
    },
});
oadrian2 commented 10 months ago

Then you need to work with WebPubSubContext input binding and in the function, you can get the values by context.extraInputs.get('wpsContext'). And inner structure is described here: https://learn.microsoft.com/en-us/azure/azure-web-pubsub/reference-functions-bindings?tabs=csharp#webpubsubcontext-1

For example:

const wpsContext= input.generic({
    type: 'webPubSubContext',
    name: 'wpsContext',
    hub: 'sample_funcchatv4'
});

app.http('message', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    extraInputs: [wpsContext],
    handler: async (request, context) => {
        let wpsRequest = context.extraInputs.get('wpsContext').request;
        let data = request.data;
        ....
    },
});

Is it the case that since the WebPubSubContext is an input and not a trigger, the trigger metadata isn't present like they are with the WebPubSubTrigger? If they aren't there when using WebPubSubContext then you can't use those values to populate other Input bindings (e.g., CosmosDB or Storage) since there isn't any binding metadata. This does limit its usefulness.

JialinXin commented 10 months ago

It's correct that WebPubSubContext is an input binding instead of trigger binding, so triggerMetadata is not valid for building WebPubSub metadata here. I'm not sure that if it's possible to bind single request to multiple input bindings. When you work with WebPubSubContext, it means the request is a Web PubSub request, why would you treat it as a Cosmos DB document? Should it read the request and then convert to a Cosmos DB document in other way? Would you describe your scenario a little bit more?

hhunter-ms commented 6 months ago

It looks like this has been resolved. Closing! #please-close