I’m working on a Forge app that uses a Forge Remote to provide data.
In the UI and through (scheduled) triggers you can make authenticated calls to the Forge Remote, but what if I need to make an authenticated call from within the Compass data-provider module?
In testing I found that just using the Fetch API results in 401 errors.
Is this something that can be added?
Or is there a workaround where I can call a method to add the authentication details to the Fetch API from the backend?
@AdamMoore I’m mentioned you as I connected with you at Team24 and because you are the author of the RFC
Some additional context: The app is for Compass and in the data-provider module you can opt to backfill data for a component. In my case the data needs to come from the Forge Remote, and since it is setup to support the Forge Remote authentication from the contract it would be nice to reuse this for the backfill of data as well.
It wasn’t included in the original RFC, but it did come up in the comments and in many discussions with developers since.
So we have been working on Forge Functions to Remotes, and we’re just working on the final testing, docs, etc. It should be going out to Preview in the next couple of weeks.
There will be a new invokeRemote function added to @forge/api that you’ll be able to use from any backend function much like you can from the UI currently.
It would also be cool if the body element of the invoke option could take an object that would be auto mapped to json and have the content-type header also applied to the request to the remote. This works for the frontend to remote invocation.
I’ve been playing around with the new feature and love it so far, and I only have 3 small feedback points:
It was not clear to me that I needed to add the compute operation to my remote, it took me a bit of time to figure this out.
The context of the ForgeInvocationToken is not populated like the other invocation to a remote are. I require this context so I can match the request to a tenant on the backend. I found a workaround, to pass the cloudId as a custom request header, but for consistency it would be great if this context matched the context given in other invocations
The body element of the options given to tine invokeRemote function is currently limited to ArrayBuffer, ArrayBufferView, NodeJS.ReadableStream, string, URLSearchParams and FormData. It would save us on coding if this element would also accept any object that can be parsed to JSON. Now I need to also set the header next to the body like this to have my remote accept the call:
We hear you, we’ll explore ways to make this clearer within the documentation. We’ve included it in the example, but if you’re working with existing remotes, appreciate this is something which may be missed.
The backend should have access to that context and be able to pass it through, however appreciate this deviates somewhat from the front-end remote invocation experience. We’ll explore this further.
I’ve passed along this feedback as well.
Really glad to hear this and a big thank you for the thorough and thoughtful feedback.
I have been keeping an eye on this because being able to invoke remote from the forge backend (eg. in an install event trigger or webtrigger) will also be very helpful for us too. Thank you for rolling out this feature so quickly and for keeping us updated!
I was initially having trouble getting this working, but it turns out I just needed to update the @forge/api dependency version. Everything is now working as expected
Thanks to this thread though otherwise I would have been permanently stuck.
Got stuck first because of not updating the @forge/api
Why is it called invokeRemote?! There are so many shared names in the forge platform. Its so easy to accidently use the wrong one.
Its not clear what operations:compute is for. Its not explained in the documentation and impossible to know that is a required field.
The very generic INVALID_REMOTE_ERR for all errors is not useful for debugging and getting unblocked.
I have managed to get this working, but I am really struggling with the fact that the context is not included here - specifically the context.cloudId which is needed to make requests to the forge storage graphQL API. I tried finding a way to send it to my remote manually, but it turns out that the getAppContext function doesn’t return it either… Is the only way to get the cloudId in forge really through a FIT from the frontend? This seems quite restrictive. I think in the meantime I will use this endpoint to get the cloudId since I already know the baseUrl of the site: https://your-domain.atlassian.net/_edge/tenant_info