CloudObjects / Blog / Creating a WebAPI object

Creating a WebAPI object

I want to follow up on our recent introduction of CloudObjects Core with a practical example in which we’re gonna add a Web API object to CloudObjects. A Web API, to clarify the terminology, is any API that can be accessed via the HTTP protocol, irrelevant of its API design paradigm. One part of fulfilling our mission of “empowering developers with APIs & more” is letting developers discover APIs and access their documentation in human and machine-readable form in our object directory, so adding your own APIs into this directory is a great idea to increase discoverability and ensure smooth integration with future products built on top of CloudObjects.

This article is a complete step-by-step guide that will take you from signing up to CloudObjects to the final published Web API object. Let’s get started!

Signing up

Signing up to CloudObjects is fast and free! The easiest way to sign up is to use an existing third party account, e.g. your GitHub account. Go to our homepage and click the Dashboard button. If you’re not signed in yet a sign-in modal will open. If you choose to use any of the listed identity providers you’ll be taken to an authorization page and then forwarded to the dashboard. If you sign in via email you’ll receive a link through which you can access your dashboard. No password required; you’ll remain signed in until you sign out and if you want to sign in again simply request another email. You can also sign in with IndieAuth if you have a personal website and configured it according to the instructions for distributed IndieAuth.

Adding and verifying a domain

CloudObjects organizes all objects into namespaces based on domains. You can add any of your domains, including subdomains, to CloudObjects. Simply go the the “Add a domain” page of your dashboard, enter the hostname and click Add Domain.

You can immediately test creating objects in your namespace but you cannot make them public before you have verified that you actually control the domain, as domain verification serves as a public proof of identity within the directory. Since the objective of this tutorial is to publish an API you need to verify domain control first. CloudObjects provides multiple methods for domain verification. Simply click the “Complete verification of this domain now” link on your domain’s dashboard page, choose a method and follow the instructions. After completing the process you should get back to your domain’s dashboard page and see that the domain has been verified. If you’ve signed in with IndieAuth and add the same domain that you’ve used for sign-in the domain will automatically be marked as verified.

Making your namespace public

When adding your domain to CloudObjects, a basic root object for your namespace is created automatically. However we need to edit this object to make the namespace public because the visibility of objects within a namespace is limited by the visibility of the namespace itself. Everything you need to know about object visibility is explained in the permission system documentation.

Object definitions are added to CloudObjects via so-called configuration jobs. You can create these jobs from files or directly type or paste an RDF document into the configuration job submission form. In this tutorial we’ll use the latter method. CloudObjects supports different serializations of the RDF format. We’re gonna use Turtle for now. I’ll explain the Turtle syntax throughout so you can easily understand everything even if you’ve never worked with this format before.

Start now by copying the following lines into the form and replace example.com with the domain you added and verified in the previous step:

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix co: <coid://cloudobjects.io/> .

<coid://example.com> rdf:type co:Namespace ;
    co:isVisibleTo co:Public .

Let’s try and understand what this means:

  • The first lines are prefix declarations for all the namespaces used in your document. As you see there’s the essential RDF syntax ontology (rdf) as well as the CloudObjects Core namespace (co). Prefix declarations make your RDF document smaller and much more readable because you only have to prefix properties with the short namespace code instead of the full URI.
  • The root object of your namespace has a COID (CloudObject IDentifier) that starts with coid:// followed by the domain and it has the type co:Namespace.
  • The final line sets its visibility to co:Public using the co:isVisibleTo property so it can be accessed by anyone.

This example has also shown some basics of the Turtle format:

  • URIs (such as COIDs and HTTP-URLs) are surrounded with < and >.
  • Short URIs with prefixes do not need those.
  • Multiple statements about an object are separated with semicolons (;).
  • A list of statements ends with a period (.).

A configuration job can contain multiple objects so we can continue with the API definition next and submit both at the same time.

Creating a basic API configuration

There is a custom ontology for the description of Web APIs defined in the Web API namespace. This ontology provides you with the vocabulary you need to describe the basics of your API as well as all API methods. We can add a prefix for this namespace (wa) as well as for RDF Schema (rdfs), which we’ll also use, to the top of our document:

@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix wa: <coid://webapi.cloudobjects.io/> .

We need a COID for your API. As you already know this identifier starts with coid:// followed by your verified domain name. You can choose between versioned and unversioned COIDs. In both cases you must choose a name for the object. If you only have a single Web API in a namespace you could simply name it API, otherwise choose another name.

The following would be the next lines of your RDF document if your namespace was example.com and you’d use a versioned COID with the name TestAPI and a version of 1.0:

<coid://example.com/TestAPI/1.0> rdf:type wa:WebAPI ;
    co:isVisibleTo co:Public ;
    rdfs:label "Test API" ;
    rdfs:comment "This is our Public API." ;
    wa:hasBaseURL <https://api.example.com/1.0/> .

Let’s walk through this again:

  • The first line declares your object and indicates its type as wa:WebAPI.
  • The second line sets its visibility; the declaration looks just as the one for the namespace itself.
  • The third and fourth line assign a label and a comment that further describe this object. These are default RDF Schema properties and can be used for objects of any type. In Turtle, string literals such as the values for these properties are surrounded with double-quotes (“).
  • The last line uses the wa:hasBaseURL property to declare your API endpoint.

You can simply copy the example and adjust all values as necessary to represent your own API. Done? Now you have written a complete object definition and can submit your job. Here’s how the whole thing could look like:

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix co: <coid://cloudobjects.io/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix wa: <coid://webapi.cloudobjects.io/> .

<coid://example.com> rdf:type co:Namespace ;
    co:isVisibleTo co:Public .

<coid://example.com/TestAPI/1.0> rdf:type wa:WebAPI ;
    co:isVisibleTo co:Public ;
    rdfs:label "Test API" ;
    rdfs:comment "This is our Public API." ;
    wa:hasBaseURL <https://api.example.com/1.0/> .

Click the Submit Job button on the form. You’ll be taken back to the dashboard and a confirmation that indicates whether your configuration job was successful or not will appear shortly. In fact you should see two messages as your job contained two objects. Assuming that the job was successful you can now view your object in the directory.

Directory URLs are simple, you just need to replace coid:// with https://cloudobjects.io/ and you have an object’s directory page URL; so coid://example.com/TestAPI/1.0 would be located at https://cloudobjects.io/example.com/TestAPI/1.0. If you go to the directory page for your namespace (e.g. https://cloudobjects.io/example.com) you can also see a listing of objects that includes your API.

Adding API methods

Now let’s add methods to your API! First however, we need to get back to editing. If you open the configuration job submission form as you did before you’d be greeted by an empty document, but don’t worry, you won’t have to type everything all over again! Just go to the directory page of your API as described in the previous section and scroll down to the RDF section. You can retrieve your object in all different RDF serialization formats. Next to those formats you’ll see a small edit icon. Click on the icon next to Turtle and you’ll be taken to the configuration job form and see your object in Turtle format ready for editing. If you look closely you’ll notice this looks different from what you entered before. Two triples with the properties co:isAtRevision and co:wasCreatedAt have been added. These are so-called implicit properties, which means they are managed by CloudObjects Core. Manual changes you make to them will be ignored. Deleting them won’t hurt either - they won’t be gone for long :).

Here’s some sample code in which I’ve designed a typical CRUD-style API around an items resource with three methods:

<coid://example.com/TestAPI/1.0> rdf:type wa:WebAPI ;
    co:isVisibleTo co:Public ;
    rdfs:label "Test API" ;
    rdfs:comment "This is our Public API." ;
    wa:hasBaseURL <https://api.example.com/1.0/> ;
    wa:hasMethod [
        rdf:type wa:APIMethod ;
        wa:hasVerb "GET" ;
        wa:hasPath "/items" ;
        rdfs:label "List items" ;
        rdfs:comment "Returns a list of items."
    ] ;
    wa:hasMethod [
        rdf:type wa:APIMethod ;
        wa:hasVerb "GET" ;
        wa:hasPath "/items/{id}" ;
        rdfs:label "Get item" ;
        rdfs:comment "Returns details about the item with the specified ID."
    ] ;
    wa:hasMethod [
        rdf:type wa:APIMethod ;
        wa:hasVerb "POST" ;
        wa:hasPath "/items" ;
        rdfs:label "Create item" ;
        rdfs:comment "Adds a new item to the list."
    ] .

Now let’s look at this code and understand what it means:

  • API methods are objects with the type wa:APIMethod and added with wa:hasMethod.
  • Use wa:hasVerb and wa:hasPath to describe the API endpoint. The path starts with / and extends the base URL. It can contain placeholders surrounded by { and }.
  • The rdfs:label and rdfs:comment work for methods, too. They’re optional.

We’ve also learned that in Turtle you can specify objects inline if you surround them with [ and ]. In RDF parlance these are called bnodes.

Go ahead: update your configuration, submit the job and check the directory page for your API. You’ll see your API methods listed there! If you don’t, wait for a moment and reload the page. Configuration jobs are processed asynchronously and the CloudObjects directory also caches objects so it can take up to a minute until your changes are visible everywhere.

Final Words

Congratulations, you have added your API to the CloudObjects directory! Of course this tutorial has only scratched the surface of the Web API ontology. If you’re curious go ahead and experiment with the other properties! You can get some ideas from our own Object API. You’ll notice there’s an edit icon on its page as well. Obviously you won’t be able to edit the existing object without permission but you can use any public object as the base of your configuration job and “fork” it. Neat, isn’t it?!

We’ll also publish further tutorials on this blog so make sure to stay tuned. Happy to get your feedback in the comments below!

by Lukas Rosenstock