CloudObjects / Blog / Pizza Time! Using CloudObjects Core for Domain Models

Pizza Time! Using CloudObjects Core for Domain Models

For fun, let’s create a semantic domain model, or ontology, for pizza, using CloudObjects! You may ask: “Why the heck would you do that?” Here’s a little background that gives a better explanation (other than being hungry and bored during a global pandemic).

When launching CloudObjects, I explained its vision of describing applications and their integrations with a semantic data model. CloudObjects Core is a storage and distribution system for objects of various types. I already showed you how to create Web API objects to document APIs. We launched phpMAE where you can build serverless PHP implementations stored and deployed via CloudObjects Core - each PHP class is an object.

You are not, however, limited to object types that CloudObjects gives you. The flexibility of RDF and Linked Data, the underlying technologies for CloudObjects Core, enables you to create data models for various purposes, even those that have nothing to do with describing cloud-scale applications. To demonstrate that, we’re going to describe pizza!

Why pizza? Food is something to which we can all relate, and it seems that pizza is probably one of the most non-controversial foods, at least until you put pineapple on it. It comes in different shapes with different ingredients, which makes it perfect for our demonstration. The idea has some history in the Semantic Web community: the conceptual model in this tutorial is loosely based on one from Protégé.

First, I’ll show you my pizza model and how I created it. Then, I’ll give you three ideas about what you can do next.

Conceptual Model and Plan

I’ll work with the assumption that a pizza has one base and one or more toppings. To describe this in RDF, I need to create the following objects:

  • An RDF class for pizza.
  • Another class for pizza bases. Then, I’ll make two instances of this class, thick crust, and thin crust.
  • A class for pizza toppings. Then, I’ll make multiple instances of this class for each ingredient that I may want to put on a pizza (yes, including pineapple!).
  • A property through which I can assign toppings to the pizza.
  • A functional property, i.e., a property that can only be used once per instance, to assign a base to a pizza.

Once all these objects are created, I can make a pizza object as an instance of the pizza class and describe its base and toppings as part of that object.

Let’s go and create these! I’ll use the Turtle language for this, which is one of the four RDF serializations used by CloudObjects. The others are RDF/XML, N-Triples, and JSON-LD. You can view the objects in any serialization in the directory.

Preparing the Namespace

I’m using the domain pizza-blog-demo.cloudobjects.io for this tutorial. Because I want my pizza ontology to be public and accessible to readers of this blog, even if they don’t have a CloudObjects account yet, I need to make the namespace public by setting co:isVisibleTo to co:Public.

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

<coid://pizza-blog-demo.cloudobjects.io> rdf:type co:Namespace ;
    co:recommendsPrefix "pizza" ;
    co:isVisibleTo co:Public .

Have you noticed co:recommendsPrefix? It is a convenient property through which you can assign a name to your namespace that is used (unless conflicting) as a short prefix when retrieving RDF from CloudObjects Core.

Creating the Classes

A class is an object with an rdf:type of rdfs:Class. As mentioned before, I have to create three of them, and they all should be public. As I don’t just want you to be able to see them in the directory but also create instances of them, I have to set both co:isVisibleTo and co:permitsUsageTo to co:Public. I’m using non-versioned COIDs to identify the objects. In the code listing below, you can see all three at once. It is possible to create a configuration job in this format. Nevertheless, the classes end up being separate objects.

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

<coid://pizza-blog-demo.cloudobjects.io/Pizza> rdf:type rdfs:Class ;
    rdfs:comment "A yummy round-shaped dish enjoyed by people all over the world." ;
    co:isVisibleTo co:Public ;
    co:permitsUsageTo co:Public .

<coid://pizza-blog-demo.cloudobjects.io/Base> rdf:type rdfs:Class ;
    rdfs:comment "A solid foundation capable of holding all the toppings." ;
    co:isVisibleTo co:Public ;
    co:permitsUsageTo co:Public .

<coid://pizza-blog-demo.cloudobjects.io/Topping> rdf:type rdfs:Class ;
    rdfs:comment "Toppings give pizzas great taste and variety." ;
    co:isVisibleTo co:Public ;
    co:permitsUsageTo co:Public .

Check out pizza:Pizza, pizza:Base, and pizza:Topping in the directory. Try clicking on the different RDF serializations as well.

Creating the Properties

A property is an object with an rdf:type of rdf:Property. To create a functional property, use owl:FunctionalProperty, which comes from the Web Ontology Language (OWL).

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix co: <coid://cloudobjects.io/> .
@prefix pizza: <coid://pizza-blog-demo.cloudobjects.io/> .

<coid://pizza-blog-demo.cloudobjects.io/hasBase> rdf:type owl:FunctionalProperty ;
    rdfs:domain pizza:Pizza ;
    rdfs:range pizza:Base ;
    co:isVisibleTo co:Public ;
    co:permitsUsageTo co:Public ;
    co:makesTriplesVisibleTo co:Public .

<coid://pizza-blog-demo.cloudobjects.io/hasTopping> rdf:type rdf:Property ;
    rdfs:domain pizza:Pizza ;
    rdfs:range pizza:Topping ;
    co:isVisibleTo co:Public ;
    co:permitsUsageTo co:Public ;
    co:makesTriplesVisibleTo co:Public .

Let’s quickly walk through a couple of new things here:

  • The rdfs:domain indicates the type (or class) of the object to which the property can be added. CloudObjects checks your configuration jobs to validate that you only use, for example, pizza:hasTopping on a pizza:Pizza but not on, let’s say, a wa:WebAPI (though, maybe even APIs get better if you top them with cheese? Who knows …).
  • The rdfs:range indicates the type for the value of the property. In this scenario, it ensures that you cannot mix toppings and bases.
  • We already introduced co:isVisibleTo and co:permitsUsageTo. With the new property co:makesTriplesVisibleTo, you can specify the visibility for the values of a property. For pizza, it makes sense that everybody who sees the pizza also learns its base and toppings. Hence, we set it to co:Public. In more practical CloudObjects Core applications, this is often used for security credentials like passwords and API keys.

Check out pizza:hasBase and pizza:hasTopping in the directory.

Creating the Pizza Bases

Next up, I’m creating two pizza bases, thick crust and thin crust, which are objects that have an rdf:type of pizza:Base:

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

<coid://pizza-blog-demo.cloudobjects.io/ThickCrust> rdf:type pizza:Base ;
    co:isVisibleTo co:Public ;
    co:permitsUsageTo co:Public .

<coid://pizza-blog-demo.cloudobjects.io/ThinCrust> rdf:type pizza:Base ;
    co:isVisibleTo co:Public ;
    co:permitsUsageTo co:Public .

Check out pizza:ThickCrust and pizza:ThinCrust in the directory.

Creating some Pizza Toppings

Now it’s time for the pizza toppings. They are objects that are instances of pizza:Topping. I’ve decided to create a few common ones:

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

<coid://pizza-blog-demo.cloudobjects.io/Cheese> rdf:type pizza:Topping ;
    co:isVisibleTo co:Public ;
    co:permitsUsageTo co:Public .

<coid://pizza-blog-demo.cloudobjects.io/Tomatoes> rdf:type pizza:Topping ;
    co:isVisibleTo co:Public ;
    co:permitsUsageTo co:Public .

The Turtle listing above shows only pizza:Cheese and pizza:Tomatoes. Apart from those, I’ve also created pizza:Pepperoni, pizza:Mushrooms, pizza:Onions, pizza:Sausage, pizza:Bacon, pizza:BlackOlives, pizza:GreenPeppers, pizza:Pineapple, pizza:Spinach, and pizza:Broccoli, which you can see in the directory. In case you wondered, I took them from my first search result for common pizza toppings. Except for broccoli, that was my preference :)

Baking a Pizza

Finally, after preparing our domain model, we can now make a pizza and use all the classes and properties we created before. My pizza is the simple classic Margherita with just tomatoes and cheese and the typical Italian style thin crust:

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

<coid://pizza-blog-demo.cloudobjects.io/Margherita> rdf:type pizza:Pizza ;
    pizza:hasBase pizza:ThinCrust ;
    pizza:hasTopping pizza:Tomatoes ;
    pizza:hasTopping pizza:Cheese ;
    co:isVisibleTo co:Public .

All right, check out pizza:Margherita in the directory. Buon appetito!

Where next?

As I promised in the beginning, I’ve shown you how I created my pizza ontology, and I’m giving you three suggestions on what you can do next. Before that, you have to have a CloudObjects account and a namespace where you can create your objects.

Get started with CloudObjects

  1. Go to the CloudObjects homepage and sign in to your existing account or create a new one, which is free and quick, especially when using an existing third-party account like GitHub.
  2. Go to the “Add a domain” page of your dashboard and add a domain. If you want to create public objects visible for everyone in the directory, you have to use and verify a domain you own. For private objects, you can also activate the test domain.
  3. If you want to make your namespace public, create a configuration job with the following content, replacing YOURDOMAIN with the domain you added in the previous step:
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix co: <coid://cloudobjects.io/> .

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

Bake a Pizza using my ontology

You can create a pizza in your namespace using the domain model that I created in mine. To do so, create a configuration job following this template:

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

<coid://YOURDOMAIN/YOURPIZZA> rdf:type pizza:Pizza ;
    pizza:hasBase ... ;
    pizza:hasTopping ... ;
    ...
    co:isVisibleTo co:Public .

Extend my ontology

Did I miss your favorite pizza topping? No problem, you can extend ontologies that others have created. Go ahead, create a configuration job following this template:

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

<coid://YOURDOMAIN/YOURTOPPING> rdf:type pizza:Topping ;
    co:isVisibleTo co:Public ;
    co:permitsUsageTo co:Public .

After that, people can create pizza objects with toppings from different namespaces. If you prefer to keep your favorite ingredient for yourself, you can drop the co:permitsUsageTo from your object, and then CloudObjects limits usage permission to your namespace.

Make your own ontology

You can create your own ontology by copying mine, creating a different model of pizza, another type of food, or even something completely different. It is an excellent exercise if you want to get more comfortable using Linked Data and CloudObjects Core. If you do so, follow the examples of classes and properties that I presented to you above and adjust them as needed. I think if you’re ready for this, you don’t need a template from me :)

Summary

CloudObjects Core can host semantic web data models. While the primary purpose for those is describing cloud-based application components like APIs, the system is flexible to describe all sorts of things. In this article, I demonstrated that with a pizza ontology I created in Turtle and submitted to CloudObjects Core. I also showed you how you can create objects based on that ontology or extend the ontology as well.

Questions?

Please leave your questions as comments on this blog post below or join our chat on Gitter. Make sure to stay tuned to this blog and @CloudObjectsIO on Twitter for future announcements and more tutorials about CloudObjects Core.

by Lukas Rosenstock

Show Disqus Comment Thread
Privacy Notice: Your IP address will be sent to Disqus when you enable comments.