Manage Web Services in Extensions

At this moment, I’m working on an Extension for Dynamics 365. One of the requirements is basically “publish an interface to an external packet”. In other words: “publish a bunch of web services”.

Now, I’m always trying to find the “best practice” for different circumstances. That’s also why I’m so deep into PowerShell – I think we should automate these “Best Practices” as much as possible ;-).

But in this case – handling web services for Extensions – I still haven’t found one – so it has become kind of a workaround instead of a best practice.

The context of this blogpost

I added this paragraph after I posted the blog – as it appeared to be not clear to most people.  So before you continue, let’s first put this post into the right context.

The ONLY way to use webservices in Extensions is by exporting it to xml with the CmdLet “Export-NAVAppTenantWebService”, and include it in your extension package.  This way, the web services will be published while installing the extension in a tenant .. and they will be removed while you uninstall the extension.  Perfect behavior!

But that’s not the context of this blogpost.

This post is about creating a (local) dev environment for being able to do (further) developments.  When setting up that environment, I need to get my data in the (at that point empty) dev environment before I can export it to that xml while creating the extension.  If we would be able to import the xml in the Dev env, than it would be an ok solution as well, but as far as I know, that is not possible… .  So how to I get the data into my new clean dev environment in an automated way?

So now let’s continue with the original blogpost 😉

A WebService should be part of the codebase

As said, we are developing an extension. And part of this extension is a bunch of web services. The way to make this possible in an extension is to export the webservices to a package with the PowerShell cmdlet “Export-NAVAppTenantWebService“.

In the background, it’s going to export some data from the “Web Service” table (well .. not really that table, but that’s not important for this blogpost) to an xml file. In short: it’s going to do an export, based on data in the DEV environment.

Now .. this “data” should be part of the code. Why? Well, just assume when someone “forks” into the codebase, he probably needs to set up a new DEV environment, apply the deltas, .. and generate the Web Services .. . Because they need to exist at the moment he’s going to build and test the extension.

In a way, I always try to do this with PowerShell (as you might have figured…), because basically I build a DEV environment with PowerShell – and the scripts that are responsible for that, are part of the source code management of my Extension – so the creation of data like this is still “sourcecontrolled” (if that’s a word at all).

How can we generate these web services?

Well, we have the “New-NAVWebService” PowerShell CmdLet that comes out of the box. Unfortunately, this doesn’t give us what we want. Because what we want, is to be able to generate a “tenant”-webservice .. basically a webservice where the “App Tenants” flag is “false”, like:

The “New-NAVWebService” cmdlet doesn’t do this.. . It creates a normal webservice. And that’s not good. We would have to manually change the flags to be able to export it to the xml.. .

Is there a solution?

Well, I didn’t solve this in a way I feel comfortable with, because I just can’t think of a decent way on how to work around this. In C/AL, it is possible to create the Web Services with code like this:

Where the “WebServiceAggregate” is a variable of the Record “Web Service Aggregate” which is temporary (important!)!

So how can I create this is in PowerShell – well, I would be able to:

  • Generate a text-file of a codeunit in PowerShell
  • Import it
  • Compile
  • Run
  • Remove the codeunit

But really .. that’s not cool, right? Anyway, you can find a raw version on my github.. . I tested it .. it does work .. but it really feels like it shouldn’t ;-).

My Workaround

So my actual (current) workaround is a simple one. Publish the web services (based on a certain prefix), and open the web service page. Then you should manually de-select the “All Tenants” checkmark for all concerning web services.

I made this into a PowerShell script that I include in every single Extension:

https://github.com/waldo1001/Cloud.Ready.Software.PowerShell/blob/master/PSScripts/NAV%20Extensions/3_CreateWebServices.ps1

Conclusion

In my opinion, this is a part where Microsoft shoud come in and foresee a “New-NAVTenantWebService” CmdLet or whatever.. . Should be easy.

If anyone has a better solution – please share :-).

5.00 avg. rating (98% score) - 2 votes

Permanent link to this article: https://www.waldo.be/2017/02/23/manage-web-services-in-extensions/

3 comments

  1. Why cant you use the existing mechanism to have web services auto-published when installing an extension by specifying them in an .xml file in the extension package?
    I am doing this in the BingMaps sample on the Gallery Image for a few pages and you can also expose stuff, which isn’t in the extension (Page 21, 22 etc.)

      • waldo on February 23, 2017 at 6:20 am
        Author

      I use that as well .. and should, because this the only way to get them out while uninstalling the extension as well.
      But this blog is not about the creation of the Extension. This is about creating a (local) dev environment for being able to do (further) developments. I need to get my data in the (at that point empty) dev environment before I can export it to that xml while creating the extension.
      If I would be able to import the xml in the Dev env, than it would be an ok solution as well, but afaik, that is not possible…
      Makes sense?

      • waldo on February 23, 2017 at 8:45 am
        Author

      I added the paragraph “The context of this blogpost” – hope that makes more sense…

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.