In this post, I’ll show you how to create your first RESTful Serverless Function.

Example:

$ curl https://ping.examples.tau.link/ping
PONG

The first thing to do is to head to console.taubyte.com, log in and create a new project. If it’s your first time, follow this quick intro here.

Create an Application

It is good practice to separate components of your projects. So let’s create an application to host our function.

  • Navigate to Applications applications-menu

  • Click on the ➕ button, this will open a modal to create an application. We’ll call it backend. Click on ✔️ to validate. create-application-backend

  • Click on the application you just created.

Create a Domain

Because we’re creating a RESTful endpoint we will need a DNS domain. If you’re not sure what DNS is check this article. If you don’t have a domain, start by getting one. If you’re not sure where to get one, here’s a good article: The Best Domain Registrars Of 2022.

  • Navigate to the Domains tab domain-tab-application

  • Click on the ➕ button, this will open a modal to create an application. We’ll call it ping_domain. Make sure you type your subdomain in the FQDN field then click on ✔️ to validate. create-ping-domain If your domain is example.com, you want to type ping.example.com

Domain validation

You need to provide proof that you own the domain in question.

In addition to this entry, you will need to redirect the DNS requests to this subdomain to the Taubyte network. To do so, add the following entry:

ping IN CNAME nodes.taubyte.com.

Depending on you’re registar, doing so would look like this: example-dns-namecheap

Once you added the entries, get back to the console and close the modal.

You can continue with the next step as, unlike anything you might have seen before, on Taubyte nodes verify the TXT record individually at run-time.

Check (optional)

You can use the modal to check for the TXT entry or use one of the many online tools available out there. As a Linux user, I prefer to use dig, so that’s what I’m going to show you:

  • To check the TXT entry you run

    $ dig txt entry-provided-by-modal
    Example: this blog at the time of writing
    $ dig txt qmpkcpkm.blog.taubyte.com
    
    ; <<>> DiG 9.16.27-RH <<>> txt qmpkcpkm.blog.taubyte.com
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42202
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 65494
    ;; QUESTION SECTION:
    ;qmpkcpkm.blog.taubyte.com.	IN	TXT
    
    ;; ANSWER SECTION:
    qmpkcpkm.blog.taubyte.com. 60	IN	TXT	"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZGRyZXNzIjoiNWRzZFcxcHRYdFRwQm9LWlY3bVNkR2Q1WFlvWnV5In0.5Iqzg3N5MzDo9ougpJveKGbzcArSo8TibXrfBMcHDstm9CtGPLymrxzXuX1d1pCs14er0P0hP1BGcLxoRvWZMw"
    
    ;; Query time: 20 msec
    ;; SERVER: 127.0.0.53#53(127.0.0.53)
    ;; WHEN: Mon Sep 12 12:49:50 CDT 2022
    ;; MSG SIZE  rcvd: 250
    Notice the answer section
    ;; ANSWER SECTION:
    qmpkcpkm.blog.taubyte.com. 60	IN	TXT	"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZGRyZXNzIjoiNWRzZFcxcHRYdFRwQm9LWlY3bVNkR2Q1WFlvWnV5In0.5Iqzg3N5MzDo9ougpJveKGbzcArSo8TibXrfBMcHDstm9CtGPLymrxzXuX1d1pCs14er0P0hP1BGcLxoRvWZMw"

  • To check the CNAME entry you run

    $ dig ping.your.domain.tld
    Example: this blog at the time of writing
    $ dig blog.taubyte.com
    
    ; <<>> DiG 9.16.27-RH <<>> blog.taubyte.com
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36156
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 65494
    ;; QUESTION SECTION:
    ;blog.taubyte.com.		IN	A
    
    ;; ANSWER SECTION:
    blog.taubyte.com.	54	IN	CNAME	nodes.taubyte.com.
    nodes.taubyte.com.	60	IN	A	20.9.66.151
    nodes.taubyte.com.	60	IN	A	20.231.58.152
    
    ;; Query time: 70 msec
    ;; SERVER: 127.0.0.53#53(127.0.0.53)
    ;; WHEN: Mon Sep 12 12:55:25 CDT 2022
    ;; MSG SIZE  rcvd: 97
    Notice in the answer section, the first line is the CNAME. The other lines are IPs provided by the network for the best-suited nodes at that time
    ;; ANSWER SECTION:
    blog.taubyte.com.	54	IN	CNAME	nodes.taubyte.com.
    nodes.taubyte.com.	60	IN	A	20.9.66.151
    nodes.taubyte.com.	60	IN	A	20.231.58.152

Create a function

All those steps led you here, the most interesting part really! Taubyte functions are WebAssembly modules, that are stored compressed in the network just like an IPFS file, and are triggered by an event. In this case, the event is an HTTP request.

  • First, switch to the functions tab functions-tab

  • Click on the ➕ button.

    • Name it ping
    • Select your domain
    • Toggle Use Inline Code
    • Select the ping_pong template.
    • Finally, Click on ✔️ to create. ping-func

The code

We’re focusing on Go, as of this article, it’s the only language that Taubyte supports.

  • The first line of code informs us of the name of the package. Because there’s a lot of automation happening under the hood to make inline code possible, we recommend to keep it to lib.

    package lib

  • Next the Taubyte Go SDK is imported. The SDK provides a friendly interface to the ABI provided by the Taubyte Virtual Machine (TVM)

    import (
        "bitbucket.org/taubyte/go-sdk/event"
    )

  • Next, is the function ping. It takes one argument which is the Event that triggered the function.

    //export ping
    func ping(e event.Event) uint32 {
    ...
    }
    It is important to export the function with //export so the TVM can call it.

  • Because a function can be triggered by events of different types, you need to check what event it is first.

    h, err := e.HTTP()
    if err != nil {
     return 1
    }

  • Given an HTTP event, we can send a message back to the client. This is done by a simple Write() call.

    h.Write([]byte("PONG"))

Full code:

package lib

import (
  "bitbucket.org/taubyte/go-sdk/event"
)

//export ping
func ping(e event.Event) uint32 {
  h, err := e.HTTP()
  if err != nil {
   return 1
  }

  h.Write([]byte("PONG"))
  
  return 0
}

Commit and Push

At this point, everything is happening inside a virtual file system hosting your repo on your browser. To make the network aware of your changes you need to push to Github.

  • Click on the big green button on the bottom right push-btn This will open a modal that will guide you through three pages:
    • Configuration changes there you will see all the diffs related to resources. In addition to all the other resources you created, under Applications > ping > Functions you can see your newly created function.

    • Code changes there you will see all the diffs related to inline code. Try to spot ping.go

    • Commit message there you should enter a commit message and click on Finish to push.

Check your repo

Now that you pushed your code, you can check the changes on github. The console has a helper to take you there:

  • Click on your avatar in the top right corner
  • Click on Project Details
  • Click on URL of the repo you want to check out

Builds

Each time you push code to Github, jobs to rebuild code and config are created by the network in response to the event. You can check those build jobs and their status on the Builds page. builds-page

Test it

You can either test it from your browser by navigating to https://ping.your.domain.tld/ping, or use curl as follow

$ curl https://ping.your.domain.tld/ping
PONG

Challenge

Modify the message, push the code and test it again.

References