>> Thank you, Donna and Greg.
I am super excited to be
sharing all things code in Custom Connector.
A little bit about myself,
I am an active Architect with Artist Consulting,
based out of Dallas Texas.
I'm also a Power addict, passionate about
all things Azure and Office 365,
the Business Applications MVP, and also the co-founder of
the Dallas-Fort Worth Power Apps and Power Automate UG.
Today, the next 30 minutes we are going to be learning or getting
a high-level overview of
what it means to embed code in custom connectors,
why the benefits of enabling code
and looking at a few example of use cases and
then also some of the top frequently
asked questions that I've had in this first release,
and also that I have seen being asked in the community.
Now before we start talking about
embedding code in custom connectors,
let's talk a little bit about what custom connectors really are.
Custom connectors are more like
a wrapper around a REST or SOAP API that
actually allows Power Automate, or Logic
Apps, or Power Apps to communicate with your back-end services.
They are useful, especially, when you
don't have a pre-built connector.
If you don't have something that's already
wrapped up and available for you,
then you can create one that can talk to your backend servers,
either a legacy system or an API layer,
and then make them available that can expose like triggers and
actions that can be used or consumed by
your users that are building solutions on the platform.
Now within custom connectors,
there is this concept of policy templates.
They allow you to add policies to
modify the behavior of a custom connector at one time.
So you can use one of the out-of-the-box templates that
can be used to perform data conversion or maybe route requests,
or you can set parameter values and more.
But what if those templates don't fit
your needs and you need to be able to go above and
beyond and transform this request and response
payloads beyond the scope of the existing policy templates?
That's where code in custom connectors actually come into play.
When code is used,
you have to remember that actually takes
precedence over the codeless definition.
Very recently, the C# code in custom connectors
was made available in public preview.
There are several things that you can do with it.
You can have complex transformation of
your payload or your incoming requests.
You can manipulate data to make it
easier for connectors to be consumed,
especially in fusion depth scenarios.
You can also add additional data to your
response or parameters to incoming requests.
You're not limited to that.
You can also send external request to fetch additional data.
Now the good thing about, especially in case of
fusion of scenarios is that you are
masking all of that and
abstracting that away from your business users.
It makes it really easy for
you being the code for step to wrap all of
that into a custom connector,
and then make it easy on your business users to consume it.
Now the next big question is how do
I get code embedded in custom connectors?
Now before you get started with writing code,
I'd highly recommend you review for
other supported classes and namespaces.
There's a blue link at the bottom of that screenshot that
has a really good write-up of sample code,
and then they also talk to you about what
the limitations are, and then
what you need to know before you start writing.
It's really helpful when you start looking at that as a reference.
Not all C# namespaces are supported at this time,
but most of the common ones like collections
or rejects or JSON link, they're all supported.
The couple of things that you want to keep
in mind when you start building is
that, right now, it's only C-Sharp code that's supported,
and you can only have one code file per connector,
and the maximum execution time
of your connector has to be five seconds.
We have to remember this isn't public preview
so things will get better in the future.
I'm sure there will be support for additional features,
and then also the max size of your code file is 1MB.
The little screenshot that you're looking at on the right,
you'll notice that you can embed
code there. You can literally upload a file,
or you can even embed C# code in there.
You have to have
a class name script that inherits from ScriptBase,
and then you also have to have an execute async method,
so these are things that you have.
You can have within the async method,
you can call other methods if you want,
but at a minimum,
these are the prerequisites to get started with it.
Next up, we'll start looking at a few demos.
We're going to be pretty light on
presentation today because I know everybody loves demos.
They want to see things working,
and it makes it easier to look at stuff virtually working.
Here is a sample public API that I have,
and what this does is just spits out
a list of user information like IDs,
email, a dummy data, that I'm
going to be using in my custom connector.
What I've done for the purposes of our demo is that
I've wrapped that behind an API and API management layer,
just so I'm going to make calls and walk you through it.
Now, you'd notice that
this call over here has a lot of chatter.
Now let's assume you are the code-first dev, and a
fusion team and your business users across
your organization are wanting to use
this API layer that talks to legacy systems.
You don't have a predefined connector out there,
so you build a custom connector for them.
Now all this, a bunch of the teams and
your business users don't really need all of this chatter around.
All they need is just this array of user information and
wrapped in an object that's more user-friendly for them.
That's what we're going to see.
We're going to see how you can embed
code in a custom connector, and
pretty much extract this data, and wrap it into a custom object,
and expose that for your business users.
So we'll take a look at how we can do that.
Now here in my custom connector UI,
and you'll notice that this is how I
have it set up, my endpoints,
I have my base URL is using an API key,
and then we have a definition.
I have my actions which is going to be getting my API users.
Nothing too complex here,
I'm just going to go on to the the Code Preview section.
When you are [inaudible] connector UI,
you will notice that there is a fault segment
called code, and it will
have preview in the text. Now you can upload the files.
Remember it has to be about one MB in size,
that's the max that it can support, or you can copy paste code too.
Now, when new start working with C# coding here,
be sure that you've tested locally because, right now, you don't
have a way to debug for the web interface,
but that's something that will be supported
and it's coming in the future.
But you'll notice that you have
a dropdown here that actually lists all my actions.
It's pretty smart in a way that you can pick
which operation do you want
your custom code to override.
When you have custom code
embedded and pointed or associated to an operation,
it means these are the lines of code that are
going to take precedence over your codeless definitions.
Now, if you don't have anything selected,
then the default behavior is it's going to apply these lines of
code or this transformation to all of your operations.
That's something you want to keep in mind.
Let's take a look at what we're doing here.
We have our script class here and then it's inheriting transcript.
When you first start from scratch,
you will see a blurb of few lines of code,
which is the Hello World example that already does all of
this outer class and the async method out for you,
and then you can comment out
the Hello World example and start plugging in your piece of code,
and that's what I've done too.
I'm basically initiating a response, and I'm going to make
a response to the backend
because I'm going to tell my custom connector,
hey do you want to make a responses,
let's go bring back my payload,
and then if it's a success,
then I want to parse my JSON,
and you'll notice that, by default, this supports Newtonsoft,
which is exciting because a lot of our responses are
in formats that you want to transform and manipulate,
so it's good news that it already supports Newtonsoft.
I'm parsing that out,
and then what I am doing is I am capturing that data object.
If you remember, we looked at
our response, and this is what I want.
I want to clear out all the clutter in this,
and so that's exactly what I'm doing.
I'm saying, just give me that data object,
but then I'm going to create my own object and make
it much more user-friendly for my business units users to look at.
I'm plugging that in and then returning that as a response.
So every time a business user uses
this custom connector and make a call to this specific operation,
they are going to see this transformed response.
They won't see any of the other properties in the JSON object
but just the data object.
Now you do have a way to test it out,
but what I'm going to do is just show you
a quick test in flow so we can look at the raw output.
It's just a simple flow,
I'm just going to be triggering it manually.
I have my action here, and I have pagination enabled,
so I'm just going to say just get me the first page of users.
So let's go ahead and get that kicked off here. Why did I do this?
Let's go back to a prior run, and let's take a look at that.
That way I can show you what that payload is going to look like.
Here's our successful run that
I ran just a couple of minutes back.
You'll notice we have made the call,
and then if you look at our raw output,
now we have a much more cleaner transform
JSONObject that our body of parameters that we as users can use.
It really does help change the way fusion things work
because now you make
it really easy for businesses to consume data.
They don't have to work through,
dropping in a bunch of select or for loops to try and
get it out in a format that they wanted to and then plug it
into a new custom app that they wouldn't create.
You have all of that done,
and then now I have a really clean list of
user information and that's pointed to my custom object.
That was a simple example just to show you how you
can extract what payload responsibility that's coming in,
extract the data, and then plug it in into an object.
Now, we're going to go ahead and take
a look at a slightly more complex scenario.
Let's say we want to do a Radix validation.
Let's say, if you are employing,
so I'm going to go get a specific user information.
But I want to make sure that
the email information in the system is actually valid.
We're going to try and use a regular expression
to make sure that the email validation runs correctly.
What I'm going to do is let's go look at our next API here.
I'm using the same public API.
You'll notice that this is the data that it sends back.
Now, when I am returning
the response through the custom connector to the user back,
I don't want to be giving them any of these.
All I want to do is just extract
the email and then run the regular expression. Excuse me.
Sorry about that.
I'm going to extract the email information,
run the regular expression,
and check if it's valid.
Then I'm going to strip out all of this.
I'm going to form my own custom object
and return back to the users,
thinking here's the user's email,
and it matched my validation.
Let's take a look at how we've built that out.
I have another custom connector pointing to
my APIM that it's backed by this public API.
Nothing too complex.
Now we have a few additional operations here.
Then I'm going to go to our code preview.
Here, you notice things are a little different.
The class and the method are the same,
just the content within it is a little different.
We're doing the same thing like we did
the last time when we were parsing the JSON out.
But this time I am navigating to
two levels to capture what the user email is for that user.
Then I'm actually parsing in what
my regular expression needs to be.
By default, it does support.
We mentioned the very beginning when you start building out,
go check out the supported namespaces because that would make it
really easy for you to plan on how you
want your code to be embedded.
I have a regular expression to validate that it's an email,
then finally, I'm transforming it.
I'm creating my own custom object that's going to
support everything else that the payload response had.
Just plug in the email and then just
tell you if it's a valid email or not.
It's going to match the expression
and tell me if it's valid or not.
What we're going to do is run a quick test here.
Now, while we wait on that to
load up, there's something that I want to do,
also point out a couple of things to know,
like when you make a change to the code embedded
customer and things that I've learned
while playing around with us,
you have to remember it's in public preview,
so things like there's going to be
updates and it's going to evolve with time.
Notice that sometimes when you make an update,
it may not reflect right away.
There it is.
Let me see if I can pull that up to
show you what that response needs to look like.
Well, that's coming back to what I was going to say.
Yes. What I normally do is I'll just add
another response to just spit out
like a dummy Ted saying, Hello World.
Then I'll test it out,
and then I'll know that I picked it up,
that the new changes have been updated.
Then I'll go back and reward my change.
It's determinant, but it's just something that I wanted to
share that I've seen that works well for me.
Well, it's taking a while,
let's give it one more minute.
Well, while we wait for that,
maybe I'll move on and talk about the
most common frequently asked questions,
and then we'll get back to this
and hopefully, it comes up by then.
These are some questions that I had when we first started, and then
also I've seen these questions come up in the community as well.
One of them is is this is a premium service?
Yes, it is because I'm pretty
much using custom connectors as an extension,
so it is a premium service. How to test code.
Today there is another way that you can just
code within the interface.
But you want to make sure that you tested locally before
you upload or use it within them.
Custom connector. If there are errors,
it does a good job of indicating that something went wrong,
but not exactly what you couldn't really
compile and it will throw an error saying something in counter,
but that's an indication that something is wrong.
So you might want to test locally before you
bring it into your custom connector.
Then how about logging and debugging?
Being code for steps,
you want to be able to log and
trace and be able to debug as your test.
Not supported at this time,
but it's on the future roadmaps, it's going to be coming.
Remember it's in public previews hopefully,
before it becomes GA it'll have all of these features.
Then can you access
values from the codeless operators in the custom connector?
We talked about how when you enable custom code,
the code is what takes priority over
codeless operations in the definition.
If you have an operation tied or associated to the custom code,
and then that runs, you cannot access
operations for that specific endpoint
that this code is applied to.
But you should be able to do it for others.
But once you have code in place,
it overrides it so you can access them.
Then any limits? This is
just a quick review of what we've talked about.
Your max execution time should be five seconds.
It has to be one MB of code file size,
has to be one code file per connector,
and you can only use the supported namespaces.
Those were the frequently asked questions that I wanted to share.
Sorry, that's what I wanted to show.
Ideally, it would be raw text that I would get back.
But let's go back just to
remind you all what
we're actually doing is we're transforming it,
we were applying a rotor expression,
and then we wanted to format our own response,
so the users don't have to work with
this whole adjacent output that got spit out of this connector.
We're just parsing the user email
and we're able to perform a regex expression.
We have a formatted and very clean-looking response.
This tells me that this is the user's email ID
and regular expression mentions a valid email ID.
It's as simple as that.
This is just a very high-level overview
of how you can embed code in custom connectors.
I'm pretty excited about it and I'm looking
forward to trying several other namespaces as well.
But I do see this being
a huge improvement in the fusion Dev scenarios, especially.
This, I wanted a quick call-out so you want to learn
more about fusion Devs and how to get involved.
Make sure that you check out the Cloud Skills challenge
and then take a look at the fusion Dev e-book.
For those of you who've joined me
today and who will watch on-demand,
thanks for taking the time. You can follow
me, and you can connect to me with these links here.
I am looking forward to hearing how
the community uses this feature to solve a variety of problems.