Calling Rust code from Node.JS - Why and How | Rust Lang | JavaScript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey welcome back and in this video i'm going to show you how we can call code that we've written in rust from node.js in the backend and that helps move us into this hybrid world where i can write code that is maybe performance oriented or cpu intensive in a language such as rust but then interrupt that from node.js and i think that's really important in this hybrid world because i don't think we're going to be in this world where we're really writing everything in one language only and i think we are in this world where we can start to mix and match and interrupt between various languages and and javascript and node.js are really well aligned to do that because rust is a high performance system level language but actually the concepts and the way rust is exposed it's very similar to javascript in that sense so the way you can export your code in in rust actually is very similar to an es6 module and therefore you can start to see this world where i can write things in node.js but then if i need something that's a little bit more high performance maybe image optimization maybe machine learning or ai then i can expose that in such a way where i can call that from javascript and i i think we get to this sort of plug-in world where we're sort of mixing matching modules and we're less intense on one language and in this video i'm going to show you exactly how to do that [Music] now if you're not familiar with rust then there will be a link appearing in the top right hand corner of my video which gives you a sort of basic getting started with rust and gives you an understanding of how it works and how to do some basic coding and get it installed on your machine but even if you don't know rust then this video is pretty simple and you should be able to follow along quite quickly but of course check out that video you know always happy for you to do that all right so let's get started so the first thing we need to do is scaffold ourselves up a clean boilerplated rust program so you see i've got an empty uh folder at the moment i'm gonna use rus package manager which is called cargo i've pre-installed it on my machine so if i want to create something brand new in cargo all i need to do is type in cargo new and then type in the name of the package or application that i want to create so in this case we're going to call it chris math and i'm just going to hit return and then as you can see it's created this binary application chris math package and if i ls into that you will see there's chris math folder and i can see there and then you see that it's it's created me some boilerplate scaffolding code so if i just type in code dot uh that is going to open that up in visual studio code as i said in my previous video i go into more detail of how cargo works and how to install the vs code extensions etc feel free to check that out so so if you know javascript already in node.js already then cargo is very similar to npm which is javascript's package manager or node.js is package manager um and as you can kind of see in the same way as i did that mpa i could do an npm in it in javascript i can do a cargo new which creates that it creates this cargo tomo file which is very equivalent to your package.json file and it gives you sort of details of what your package name is and any dependencies that you may have we're going to keep it quite simple in this application we're not going to sort of create any dependencies now that we've got the cargo tunnel there if we look in here for a second you see under the source folder there's a file called main.rs by default what will happen with rust is it will create you a sort of main.rs which is your sort of entry pawn file and it will create you an entry point function called main and as you see this creates a hello world program so and that'll just output hello world if i go into my machine for a second then i type in cargo run which is very similar to an npm run you'll see it compiles that file and then it creates the hello world routine and i can just change this i can say hello everyone and if i save that um and then just a cargo run again you see it comes back with hello everyone and as i sort of explained in my other video it's a compiled language and it basically creates this target folder which contains the binaries underneath so if i remove this target folder let's do an rn minus rf target that's gone and then if i do a cargo build that will build it without running and then you'll see that target folder is recreated and then if i do a cargo run it's going to execute my code again and say hello everyone so that that's my basic folder what we want to do is we want to create something that will add two numbers together and we'll do it a couple of steps and then we're going to expose that back to node.js so i'm going to create a little function here i'm going to call it fn add two numbers and it's going to take in two parameters which is uh which is going to be integers so in this case uh i'm going to have a parameter called n1 and it's going to be of type i 32 so it's a 32-bit integer and then i'm going to have a parameter called uh n2 which is going to be a 32-bit integer as well and that is going to return a 32-bit integer so we'll just open that up there and all i'm going to do is i'm going to add these two numbers together for simplicity i'm going to do a return n1 plus n2 and semicolon terminate that you'll see it's not not used at the moment in rust i don't really need to do that rust supports functions and it can do expressions so if i wanted to rather than sort of return as a statement there if i just did an n1 plus n2 without return statement without semicolon then it would treat that as an expression and basically whatever the last statement is in the in my function it will return so i i've got two options there um i kind of like returning things i like being explicit so i'm just going to return that and send me kill on that so the next thing i need to do there for is um show what that value is there so i'm going to i'm just going to create something i'll do a let result equals add two numbers and i'm going to pass in the number 25 and the number um let's pass in the number 10 so we should get 35 as an answer and then i'm just going to write something that says at 10 25 plus uh [Music] 10 equals and then what you can see is a little bit of code format and here rust with this print ln statement which is a sim equivalent to kind of console.log or equivalent to a printf uh that'll just output whatever is on the screen but this little symbol here uh these curly brackets allows you to pass in any sort of variable in there and that'll get displayed so if i just put in result here then that will get displayed i need to semicolon terminate that uh just so you know russ is a semicolon terminated language it's not like javascript where i can sort of optionally do it in and out it's is pretty strict about it and then if i just do a cargo run you see it comes back with this 25 plus 10 equals 35. all right so what we're going to do now is we're going to take this function add two numbers and we're gonna make that available to node.js and the way we're gonna do that is by taking it out of the the main file and make it available in its own module so the way we do that in in rust is we need to create ourselves a lib.rs which is going to represent our kind of library module that we've got here and i'm going to pull the function that we created the add two numbers out of my my main file and i'm gonna shove it into this uh lib.rs that we just created so that's now created it's coming up with this error that it's never used now the first thing before we try and call it node.js we just want to make sure that our module works from our calling program or main.rs or entry point so what we can do here is because by default rust doesn't allow you to call anything outside of its kind of scope modules we need to bring that into scope there so to do this uh everything by default in a module is um is private so we need to make this uh public so that we can call it so i'm just going to add the word pub to this function so that will now take the add to numbers function and make that public and then that means i should be able to call that within my main function so if i now click on that add to numbers you see on my screen this light bulb has appeared and that's because i'm running visual studio code intellisense but if i click on the light bulb and you see it says line three add use chris math add two numbers so there we go um by default a little bit of uh code completion magic there um it's allowing us to import the add two numbers function from the chris math module that i created so that's that's kind of cool there and now if i save that and then if i do a cargo run over here he says compile that and it's come back with the answer 25 plus 10 equals 35 so that's pretty cool um but we need to do a little bit more what we actually need to do is make the attitude numbers available to calling programs so first thing i need to add in here is this extern keyword and what that's essentially meaning is it means that it should be callable from a c style interface so that allows me in the future to create a c program or in our case a node.js program and it will the rust compiler is going to expose a c-style uh interface so i can call that from the outside world so that's the first thing that i need to do and because i'm creating a dynamic language i need to keep consistency of my function names and therefore i need to add this sort of no mangle uh keyword or attribute at the top here um just so that we know the compiler is not going to change that name add two numbers to something else it's going to use the name add two numbers so that's all i need to do from uh my my lib.rs um and then if i save that this will this will continue to work so if i click cargo run you see it's still running over here 25 plus 10 equals 35. the next thing i need to do now is go back into my my tomo file and then i need to just expose a few attributes there um so that i can uh expose my package to the outside world so the way i do that is um if i just uh create a new attribute here we'll call that lib so i've got a new section called lib i'm gonna give it uh a name so i'm gonna give it the same name as before chris math but i could call it anything i want by default it will use the uh the overall package name and then what i need to do is set some types so way we do that is we type a create a crate type um so crate is the kind of the the thing that cargo is exporting so it's the library types that we have and by default crate will expose an rlib so a rust library and that allows me to use things kind of internally so i need if i want that main file to continue to compile and work i need to have that rlib in place uh so i can call from main but what i need to do is create this cdy lib so this c style dynamic library and that's the library file that node.js is going to use uh to to interact so if i save that now if i just do a cargo build again or even if i do a cargo run i see my 25 plus 10 equals 35 still working but if i if i were to remove that our lip for a second let's just remove that and hit save and then i ran a cargo run you would see it comes back with this use of undeclared crate or module chris math which is just because i'm i'm calling it from this main that's why i need that rlib if you are just exposing a module directly and you want to use it in node.js and you haven't got any rust calling programs and obviously you wouldn't need to use that rlib and you could keep it as just cdylib so that's that and then if i come back here and then cargo build that and back in a nice position so next thing i'm going to do is if i just look in the targets for a second you can kind of see under uh debug there you you start to get an idea of all the things that are being generated so you see um the lib chris math our lib that was the the rust library that i'm i'm using but that lip crisp underscore math the dy lip that is the the the library we're going to use to call from node.js yeah so just be aware how that works but that's the thing that that generates there so okay so i've got that working there now what i'm going to do is i'm also going to do a release build um so i just get a bit of an optimized build so if i come back into here so it's cargo build release and then now i've not just got the debug folder but i've got the release folder as well and then same thing you can see the the dui lib and the rlib has been generated there for me as well so we're in a good position now what we're going to do is call that code from rust so first thing i'm going to do there is i'm going to create myself a new shell terminal so we'll just uh create that you can see i'm in this sort of chris math folder at the moment so i'm just going to go up a file and then i'm going to create myself a new folder and we will call that um let's call it call uh rust from node so that's my new folder we'll just uh cd into that so i'm pretty clear there and then i'm just going to do an npm in it and we'll just uh hit return there lots and lots of times yes and now i have an empty folder with a package.json file for my new node application and if i just type in code.here we'll close that for a second there's my package.json and then i'm sort of ready to start coding things up so first thing i'm going to do is i'm going to create a new folder or a new file i'm just going to call it index.js and just being super lazy in that sense and what i'm going to do now is i'm going to create a little node routine that is going to call that file that we just created so the first thing i need to do is i'm going to use a forum file interface you can do these things natively which gives you a bit more performance the forum file interfaces uh you know it's it's a little bit of an expensive operation but it's fine in this case so i'm just gonna call that and i'm gonna do a require and i'm gonna use a routine called ffi napi which is a forum file interface package that you can use to make uh the c style uh call and permission so i need to install that on my machines if i do an npm install we'll do a minus minus save and we'll have that ffi um and a pi um and we'll just install that we'll save that as a package dependency take a few seconds and once that's installed then we're good to go on that so that's that's done and then if we come back into my package json for a second you can see that's been added as a dependency there so we've now got that there and what i want to do is now expose my lib and how i do that is i do dot library and what i need to do is refer to the dui lib that i that i created two seconds ago so how i'm gonna do that is i'm just going to do dot dot so it's going to be one folder up from where i'm calling from it was in a folder called chris math if you remember and then we're going to go to the target release folder and it's going to be the lib chris math and we we don't need to put the the dui extension so if i come back to here for a second uh let's just look at that you can see target release and you can see that lib chris underscore math dy lib that's that's what i'm going to use and that's the extension file there so that's fine let's come back into here i'll go back into vs code for a second and now that's uh kind of running there what i need to do is uh open some uh curly brackets there and i need to pass in the name of the function that i'm calling so we called our function add two numbers uh there we go and then next thing i need to do is specify the return type which in this case was an int and then i need to pass in any input parameters so remember i had two parameters n1 and n2 and they were both of type in so i just put in int and then int there we go close off my square brackets there and then i just close off the curly there and we just remove that curly bracket over here and then we're in a good position and now because i've got this lib uh using the forum file interface to call my add two numbers i can just call it as i would do normally so if i do a let result equals lib dot add two numbers and i can pass in uh whatever i want so you can see i've all got a completion arc zero arc one expect number returning a number so i'll just type in maybe 100 plus 50 um it's going to put the result back to here and then i'm just going to console.log out what the result was and console.log the result and now if i come back into my node folder and type in nodeindex.js i should get 150 coming back which it does so now as you can see i have a nodejs application calling a rust library that is super cool now that opens up a whole heap of functionality that was hard to do in the past so you can start to do things like calling things like hugging face i'll do a video on that for aiml you can do cpu intensive routines maybe like a fibonacci function or a search or something and that allows you to just start mixing and matching node.js and uh and rust routines so we're getting away from this kind of i build everything in one language but it allows me to start using rust for certain routines and and javascript for others and i start to get the best of both worlds in these cases now of course you could also not just do this via the forum file interface or native calls you could actually export out to webassembly and of course i've got another video on how to call webassembly from node.js so in the same way as i've exported this out as a kind of a native rust library what i could do is create a web assembly file and i'll have another video that shows you how to do that and then have my node.js call to webassembly or even i could take my webassembly and run it on browser but i'll cover that in another video i hope you can see that this world of hybrid code and being able to switch between different languages is going to become super important and i think rust is probably one of the key languages that gives us that nice interoperability because it matches really well to javascript and npm and the package model and es6 module so i think i think there's a it's really in easy to interface between the two and i see this world uh sort of getting deeper and deeper for integrations anyway i hope this video has been useful and i'll catch you on our next one
Info
Channel: Chris Hay
Views: 424
Rating: undefined out of 5
Keywords: chris hay, chrishayuk, rust programming, rust programming tutorial 2021, node.js, foreign file interface, javascript, rustlang, rust lang
Id: kkc2Z_PI8E8
Channel Id: undefined
Length: 21min 11sec (1271 seconds)
Published: Mon Oct 11 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.