Your first data model
A data model in Benno essentially defines which properties you expect to exist, and what type you expect their values to be. For example, when someone creates a new Pod, they will usually have a profile (identified by their WebID, the URL to their profile) with a link to the root of their Pod, and optionally a name:
import { buildModel, type ModelValue } from "benno";
export type ProfileThing = ModelValue<typeof profileModel>;export const profileModel = buildModel() .addProperty({ alias: "podRoot", property: "http://www.w3.org/ns/pim/space#storage", type: "url", required: true, }) .addProperty({ alias: "name", property: "http://xmlns.com/foaf/0.1/name", type: "string", required: false, });You can then use this model to fetch data from a location where you expect the data to match your model. Every Solid user has a WebID, a link to their profile, so we’ll use our profile model to fetch that data:
import type { UrlString } from "@inrupt/solid-client";import { profileModel } from "./profile-model";
async function fetchProfile(webId: UrlString) { // With the model in hand, Benno can fetch the data for you, validate that it // matches the expected shape, and then return a regular JavaScript object // that uses the `alias`es that you defined to make the validated data // available: return profileModel.fetchOneFrom(webId);}If you run the above example, you can see that the model allows you to fetch data and receive it as a plain JavaScript object. It also comes with TypeScript type definitions out of the box, so your editor will warn you if you try to access properties that the model has not validated, without you having to do anything for it.
Notice how:
- property URLs are converted to the friendly aliases you defined,
- TypeScript knows the exact shape of this object, and
- missing optional properties are
undefinedrather than causing errors.
TypeScript integration
Section titled “TypeScript integration”One of Benno’s key benefits is automatic TypeScript support. Your editor will:
- autocomplete property names as you type
profileData., - warn you if you try to access non-existent properties, and
- show you the exact types of each property.
const profileData = await fetchProfile(webId);
// ✅ TypeScript knows this is `string | undefined`const name = profileData.name;
// ❌ TypeScript error: 'email' doesn't exist on this modelconst email = profileData.email;