Recently, there has been a lot of buzz around the term "serverless". To those unfamiliar with the space, the implications of serverless architecture can sound confusing, or even too good to be true. After all, how can code run without a server, let alone run scalably?

"Serverless" is a bit of a misnomer (the servers still exist!). However, the underlying concept of abstracting away server woes is a fantastic one. Serverless architecture promises infinitely scalable, highly available, self-healing web services without having to deal with the tedium around server management -- push your code and it just runs.

In this article, I'll show you how easy StdLib makes the process of building scalable web services by first walking you through setup and basic service creation, then show you how to integrate functions from our registry to make a live music recommendation engine. If you're already familiar with StdLib, you can skip the setup steps, create a service, and go right to the good stuff at the end!

If you haven't heard of StdLib, we've created a package management ecosystem for APIs and web services, in the same vein as npm, including a registry that harnesses serverless technology to run code. We've also streamlined the process of creating and deploying code to a few simple commands using our CLI. This lets you ship code faster than ever before. We've also added some goodies like automatic type checking, analytics, and rate limiting to make developing and managing these services a breeze.

To begin, first make sure you have at least Node 6.x installed, available from the official Node.js website. StdLib also supports Node 7.x and 8.x if you'd like to use features like async await in your services.

Next, install the StdLib CLI tools by running:

$ npm install lib.cli -g

After that finishes installing, the next thing you'll want to do is create a workspace. Create a new directory you intend to build your services in and initialize the workspace.

$ mkdir stdlib-workspace $ cd stdlib-workspace $ lib init

You'll be asked for an e-mail address to log in to the StdLib registry. If you don't yet have an account, you can create one from the command line. Now you're ready to create your first service!

Once you're in your workspace, create a service by running:

$ lib create

You'll be asked to name your service. This command will automatically generate a service project scaffold in stdlib-workspace/<username>/<service> .

Once created, enter the service directory:

$ cd your-username/your-service

In this directory, you'll see something like:

- functions/ - __main__.js - package.json - env.json - WELCOME.md - README.md

At this point, there's a "hello world" function that's been automatically created ( __main__.js ). StdLib comes paired with a simple lib command for testing your functions locally and running them in the cloud. To test your function:

$ lib . "hello world"

If we examine the functions/__main__.js file, we see the following:

module . exports = ( name = 'world' , context , callback ) => { callback ( null , `hello ${ name } ` ) ; } ;

We can pass parameters to it using the CLI, either in order:

$ lib . "jon snow" "hello jon snow"

Or named:

$ lib . --name "dolores abernathy" "hello dolores abernathy"

Note that context is a magic parameter (automatically populated with execution details, when provided) as is callback (terminates execution), so these don't need to be documented and can not be specified as parameters when executing the function.

Type Checking

StdLib functions implement the open FaaSlang specification to automatically type check function inputs and outputs. You'll notice that your created function signature has some docs above it:

module . exports = ( name = 'world' , context , callback ) => {

The @param {string} name docstring means that this function expects a parameter named name to be a string . If no parameter is provided, it will use 'world' as a default value (set in name = 'world' ). If you remove the default value and do not provide an input parameter, the function will throw an error.

To see an example of the type checker in action, try changing the @param {string} name docstring to @param {number} name and removing the default value for name, then run lib . --name "jon snow" . You'll get an error that looks like this:

[name] invalid value: "jon snow" (string), expected (number)

StdLib also automatically checks return values. In the above example, the line @returns {string} makes it so that if your function returns something other than a string, you'll receive an error.

Try playing around with it a bit! You can specify several different types for function arguments and results, as documented here. Additionally, you can specify any as a type if you want to allow any result.

There's a lot more to FaaSlang than what I've covered here -- for instance, it's also an interface for service providers as well, which enables users to easily switch between any two providers that implement the spec. I'd encourage you to check it out in more detail, or contribute to it here.

When you're ready, change the function signature back to what it was previously. Then, push your function to a development environment in the cloud as follows:

$ lib up dev $ lib your-username.your-service[@dev] --name "sansa stark" "hello sansa stark"

And to release it (when you're ready!)

$ lib release $ lib your-username.your-service --name "sansa stark" "hello sansa stark"

It's that simple!

By default, "publish": true in the stdlib key of your package.json file is set for new services. This means that services you deploy to release environments will appear in the public registry. Services deployed to development/staging environments will not appear in the registry.

Staging environments (like the one created with lib up dev ) are mutable and can be replaced indefinitely. Releases ( lib release ) are immutable and can never be overwritten. However, any service can be torn down with lib down <environment> or lib down -r <version> (but releases can't be replaced once removed, to prevent mistakes and / or bad actors).

Your service is now available as an infinitely scalable HTTP endpoint at the following URL:

https://<your-username>.stdlib.com/<your-service>/?name=arya%20stark

Try navigating there in your web browser. You can specify arguments as URL params, as shown above.

The lib Package

We also provide an easy, intuitive way to call this service and other services in our registry from code via our Node.js SDK, lib . Install it by navigating to your project's directory, then running:

$ npm install lib --save

You can now use the lib package to easily call any function from our registry by requiring it as const lib = require('lib') . As an example, you can turn your new service into a music recommendation engine by calling the service jacoblee/recommendMusic from our registry. If you look at jacoblee/recommendMusic 's page in our registry here, you'll see that the service does it's best to match an input string to an artist, then returns an array of recommended music based on the input.

We'll use jacoblee/recommendMusic within our service, but the service we'll create will do some parsing to output a single string corresponding to a song rather than an array of them. To do this, you can create a new service to do this as we did above, or you can reuse the one you've been using in this tutorial by creating a new function called music within your service. If you want to create a new function, run the following command from your service directory:

$ lib function:create music

Then copy the following function into functions/music.js:

const lib = require ( 'lib' ) ; module . exports = ( artist , context , callback ) => { lib . jacoblee . recommendMusic [ '@2.0.0' ] ( { artist : artist } , ( err , tracks ) => { let track = tracks [ Math . floor ( Math . random ( ) * tracks . length ) ] ; return callback ( err , track ) ; } ) ; } ;

This function will be exposed as a separate endpoint within your service. Try running your new music endpoint locally as: ​

$ lib .music --artist <your favorite artist>

And you'll see a nice song recommendation! You can upload this service the same way as before using lib up dev or lib release . To hit this new endpoint, you'll have to specify music as a function name:

https://<your-username>.stdlib.com/<your-service>/music/?name=daft%20punk

So what have we done here? We've used the lib package to call a StdLib service that provides music recommendations, then pick a random song from the output and return it. The syntax is quite simple -- simply lib.<username>.<service name> with an optionally specified version number (you would call dev services this way as well), followed by the arguments and a callback. This makes it very easy and natural to combine different services to create more customized, powerful functionality!

If you're avant-garde and are using async await with Node 7.6+, your function can look even cleaner:

const lib = require ( 'lib' ) ; module . exports = async ( artist , context ) => { let tracks = await lib . jacoblee . recommendMusic [ '@2.0.0' ] ( { artist : artist } ) ; return tracks [ Math . floor ( Math . random ( ) * tracks . length ) ] ; } ;

See the docs for a complete list of ways you can call functions.

After you've deployed a service (to a dev environment or as a release) you can go to your StdLib dashboard to manage your service. You can see how often your services are being called, rate limit your service, and even set pricing! There are also a whole host of additional features around consuming and developing web services, such as authentication and team support, that we hope you'll find useful.

That's it! You now have mastery over building a service, testing it in a development environment online, releasing it for private (or public) consumption, and calling services from our registry. We're always on the lookout for cool projects built on our platform, so please let us know if you build anything exciting that you would like us to feature or share! We are also the easiest way to create Slack bots, Twilio forwarding services, Alexa skills, and more through our template system.

We're continually rolling out awesome new features -- to stay tuned, follow us on Twitter @StdLibHQ or join our Slack channel (get an invitation by clicking the button under the community tab on our main website. Thanks for reading!

Like this article? Follow @hacubu on Twitter