At LeanKit we’re always creating new integrations with other software and sites. Most of them involve reading from a 3rd party application’s web service API (Microsoft’s TFS via VisualStudio.com, JIRA, GitHub issues and more), performing some type of translation and mapping of the data, and then writing to LeanKit’s web service API to manipulate (add, update, remove) cards on a board. Some integrations also read from LeanKit and write to the target application to provide 2-way syncing of data.
Well we could create a web service interface to act as a facade for communicating with the library and consume that in our Node application. That’s a decent option and one we considered. Instead we decided to take a look at Edge.js.
Enter Stage Left: Edge.js
What is Edge.js? Pure .NET & Node awesomeness. According to the introduction: Edge.js connects Node.js and .NET ecosystems … on Windows, MacOS, and Linux in one process.
I first learned about Node.js from my super smart friend and co-worker
David Neal: How to leverage SQL Server with Node.js using Edge.js
In layman’s terms: Edge.js allows you to run .NET code in the Node process. Yes, .NET code inside Node! It obviously works on Windows but will also work on MacOS and Linux using Mono as long as the underlying .NET code you are using will run on Mono. In our case the CSOM library we are using will only work on Windows.
Other than my brief explanation above and the examples below I will not provide detailed information about Edge.js, both David’s article and the Edge.js documentation offer plenty of introduction material, quick-start examples, etc. I’ll assume that since you are reading this that you either have some experience with Node or at least some interest so I will not provide details for installing Node or setting up your Node environment, NPM (Node Package Manager), etc.
Wrap that Wrapper
I don’t need to expose everything that the CSOM API can do to my Node application. I only need to perform a few operations like getting a list of projects and getting a list of tasks for a project. In real life I need to do a few other things like attempt to authenticate a user, add a task, update a task, get a list of team members and more but getting projects and tasks should work well for this demo. To simplify code navigation, readability and testing we’ll create a class, ProjectServerClient, to serve as a wrapper to the CSOM API that will only provide the functionality we need. getting projects and tasks. If you have worked with the SharePoint/Project CSOM before then the below code will look somewhat familiar. I fully admit to not being a SharePoint developer so there may be much better ways to do what I’ve done in the example code. Feel free to offer helpful insight, tips and suggestions.
Some things to keep in mind:
- Your .NET project’s platform version must be .NET 4.5 or higher because you need Async/Await support for working with Edge.js.
- You will need to install the Microsoft Office SharePoint Server 2013 Client Components SDK on your dev box as well as on any machine where this code will run.
- You will also need to reference the Micorosoft.ProjectServer.Client dll which you can get from the Project 2013 SDK.
- You may also need to enable/install Windows Identity Foundation.
- This example uses the SharePointOnlineCredentials to communicate with Project Online (Office 365). If communicating with an on-premise (or other-hosted) installation of Microsoft Project Server you can use NetworkCredentials to authenticate.
Now that we have a simpler .NET library to work with it needs to have an interface that Edge.js understands. We could convert all of our methods to Async/Await but I will leave them as-is for code reuse purposes and instead create a wrapper for the wrapper, EdgeProjectServerClient.
Now we have a couple of methods with signatures that Edge.js can understand. Next we’ll add code to our Node.js app to call into this .NET library.
Node + Edge > Node
Let’s create a module that acts as a client library for talking to our .NET code via Edge.js and call it client.js. Our module will simply expose a couple of methods: getProjects and getTasks, which map to the similarly named methods in our .NET library.
We simply require the “edge” module and then create a proxy for each .NET method we want to call using Edge’s .func() method, think of it as an anonymous function. The getProjectsMethod and getTasksMethod methods are examples of creating the Node.js proxy to a .NET method by specifying the .NET assembly, class and method name. Later we invoke the .NET methods by invoking the getProjectsMethod and getTasksMethod functions. Note: “dlls” is the name of a folder that is a sibling to the Node src folder. It is where I store the dll for the library that contains the ProjectServerClient and EdgeProjectServerClient classes described above in addition all its dependencies.
Finally we just need to write some code in our index.js file that uses our client module to talk to Project Online. Let’s just get a list of our projects and write the name of each to the console. Assuming we have everything installed and setup properly we only need to start up our Node app and it will print out a list of projects hosted on Project Online.
Running this file via the command line with the command “node [Path To File]/index.js” results in the below output which is a list of all my projects on my Project Online site!
Building out additional functionality like getting tasks for each project, getting a list of team members, updating a task, etc. is just a matter of continuing down the same path that we have already started together.
Hopefully you’ll find leveraging your .NET code base with Edge.js as useful and interesting as I have. If you have any questions feel free to give me a shout via the comments below or on Twitter: @danhounshell.