Skip navigation

Use strongly-typed models

Strongly typed models are programmatic representations of the content types in your Kontent project. They help you map the content retrieved from the Delivery API (which comes in the form of JSON objects) directly to a model you can use in your code.

Table of contents

    Life without strongly typed models

    When getting content directly from the Delivery API, you receive content items as JSON objectsOpens in a new window. Your application then needs to parse the JSON to display your content. For example, you access a Headline element of the example content item like this: response.item.elements.headline.value.

    Here is an example of retrieving, parsing and displaying a small content item.

    In a more complicated scenario, this approach becomes cumbersome. It forces you to remember the JSON structure of your content items and the codenames of your content elements.

    To make this easier, use a Delivery SDK so that you can map the retrieved content items to their strongly typed models.

    Use strongly typed models

    This practice has several advantages:

    • type safety during compile-time
    • convenience (IntelliSense remembers content type properties for you)
    • support of type-dependent functionalities (such as display templates in MVC)

    The models are plain classes that don't have any attached behavior or dependency on an external framework. Each model corresponds to a content type in your Kontent project.

    Here is the Homepage content type used in the previous TypeScript code example.

    A screenshot of a homepage content type

    Sample Homepage content type

    To create a content type's representation in code, you need a class with properties representing the individual content elements:

    • Each property is mapped to its content element's codename either explicitly or using a naming convention. For example, codename body_text becomes property bodyText.
    • Properties are usually typed using classes provided by the SDK.
    • Depending on the SDK, simple content elements (like text and number) are sometimes represented using native types (like string and integer).

    The following example is a strongly typed model of the Homepage content type.

    • Java
    // Tip: Find more about Java SDK at https://docs.kontent.ai/java import kentico.kontent.delivery.Asset; import kentico.kontent.delivery.ContentItemMapping; import kentico.kontent.delivery.ElementMapping; import kentico.kontent.delivery.System; import java.lang.String; import java.util.List; /** * This code was generated by a <a href="https://github.com/Kentico/kontent-java-packages/tree/master/kontent-delivery-generators">kontent-generators-java tool</a> * * Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. * For further modifications of the class, create a separate file and extend this class. */ @ContentItemMapping("homepage") public class Homepage { @ElementMapping("body_text") String bodyText; @ElementMapping("headline") String headline; @ElementMapping("picture") List<Asset> picture; System system; public String getBodyText() { return bodyText; } public void setBodyText(String bodyText) { this.bodyText = bodyText; } public String getHeadline() { return headline; } public void setHeadline(String headline) { this.headline = headline; } public List<Asset> getPicture() { return picture; } public void setPicture(List<Asset> picture) { this.picture = picture; } public System getSystem() { return system; } public void setSystem(System system) { this.system = system; } }
    // Tip: Find more about Java SDK at https://docs.kontent.ai/java import kentico.kontent.delivery.Asset; import kentico.kontent.delivery.ContentItemMapping; import kentico.kontent.delivery.ElementMapping; import kentico.kontent.delivery.System; import java.lang.String; import java.util.List; /** * This code was generated by a <a href="https://github.com/Kentico/kontent-java-packages/tree/master/kontent-delivery-generators">kontent-generators-java tool</a> * * Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. * For further modifications of the class, create a separate file and extend this class. */ @ContentItemMapping("homepage") public class Homepage { @ElementMapping("body_text") String bodyText; @ElementMapping("headline") String headline; @ElementMapping("picture") List<Asset> picture; System system; public String getBodyText() { return bodyText; } public void setBodyText(String bodyText) { this.bodyText = bodyText; } public String getHeadline() { return headline; } public void setHeadline(String headline) { this.headline = headline; } public List<Asset> getPicture() { return picture; } public void setPicture(List<Asset> picture) { this.picture = picture; } public System getSystem() { return system; } public void setSystem(System system) { this.system = system; } }
    • C#
    // This code was generated by a kontent-generators-net tool // (see https://github.com/Kentico/kontent-generators-net). // // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. // For further modifications of the class, create a separate file with the partial class. using System; using System.Collections.Generic; using Kentico.Kontent.Delivery.Abstractions; namespace KenticoKontentModels { public partial class Homepage { public const string Codename = "homepage"; public const string HeadlineCodename = "headline"; public const string BodyTextCodename = "body_text"; public const string PictureCodename = "picture"; public string Headline { get; set; } public IRichTextContent BodyText { get; set; } public IEnumerable<IAsset> Picture { get; set; } public IContentItemSystemAttributes System { get; set; } } }
    // This code was generated by a kontent-generators-net tool // (see https://github.com/Kentico/kontent-generators-net). // // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. // For further modifications of the class, create a separate file with the partial class. using System; using System.Collections.Generic; using Kentico.Kontent.Delivery.Abstractions; namespace KenticoKontentModels { public partial class Homepage { public const string Codename = "homepage"; public const string HeadlineCodename = "headline"; public const string BodyTextCodename = "body_text"; public const string PictureCodename = "picture"; public string Headline { get; set; } public IRichTextContent BodyText { get; set; } public IEnumerable<IAsset> Picture { get; set; } public IContentItemSystemAttributes System { get; set; } } }
    • TypeScript
    // Tip: Find more about JS/TS SDKs at https://docs.kontent.ai/javascript import { ContentItem, Elements } from '@kentico/kontent-delivery'; /** * Generated by '@kentico/kontent-model-generator' * Timestamp: Tue Sep 24 2019 15:07:22 GMT+0200 (GMT+02:00) * * Tip: You can replace 'ContentItem' with another generated class to fully leverage strong typing. */ export class Homepage extends ContentItem { public headline: Elements.TextElement; public bodyText: Elements.RichTextElement; public picture: Elements.AssetsElement; constructor(){ super({ propertyResolver: ((elementName: string) => { if (elementName === 'body_text'){ return 'bodyText'; } return elementName; }) }) } }
    // Tip: Find more about JS/TS SDKs at https://docs.kontent.ai/javascript import { ContentItem, Elements } from '@kentico/kontent-delivery'; /** * Generated by '@kentico/kontent-model-generator' * Timestamp: Tue Sep 24 2019 15:07:22 GMT+0200 (GMT+02:00) * * Tip: You can replace 'ContentItem' with another generated class to fully leverage strong typing. */ export class Homepage extends ContentItem { public headline: Elements.TextElement; public bodyText: Elements.RichTextElement; public picture: Elements.AssetsElement; constructor(){ super({ propertyResolver: ((elementName: string) => { if (elementName === 'body_text'){ return 'bodyText'; } return elementName; }) }) } }

    Generate models

    We recommend that you generate the models using the TypeScript/JavaScript model generatorOpens in a new window.

    We recommend that you generate the models using the .NET model generatorOpens in a new window.

    We recommend that you generate the models using the Java model generatorOpens in a new window.

    To use the model-generator tool, follow the instructions in its README.

    You can then use the generator to create strongly typed models from your Kontent project by providing your Project ID.

    • Java
    // For instructions on using the Java model generator, visit https://github.com/Kentico/kontent-java-packages/tree/master/kontent-delivery-generators#run-as-a-gradle-task // Configures Gradle plugin import com.squareup.javapoet.JavaFile import kentico.kontent.delivery.DeliveryClient import kentico.kontent.delivery.DeliveryOptions import kentico.kontent.delivery.generators.CodeGenerator buildscript { repositories { jcenter() } dependencies { classpath('com.github.kentico:kontent-delivery-generators:latest.release') } } // showcase task task generateModels { doLast { // The most complex solution, you could configure the client as you want // i.e. set preview API key DeliveryOptions options = new DeliveryOptions(); options.setProjectId("975bf280-fd91-488c-994c-2f04416e5ee3"); DeliveryClient client = new DeliveryClient(options); CodeGenerator generator = new CodeGenerator( options.getProjectId(), 'com.kentico.kontent.test.springapp.models', file('src/main/java') ); List<JavaFile> sources = generator.generateSources(client); generator.writeSources(sources); } } // Runs generateModels task ./gradlew generateModels
    // For instructions on using the Java model generator, visit https://github.com/Kentico/kontent-java-packages/tree/master/kontent-delivery-generators#run-as-a-gradle-task // Configures Gradle plugin import com.squareup.javapoet.JavaFile import kentico.kontent.delivery.DeliveryClient import kentico.kontent.delivery.DeliveryOptions import kentico.kontent.delivery.generators.CodeGenerator buildscript { repositories { jcenter() } dependencies { classpath('com.github.kentico:kontent-delivery-generators:latest.release') } } // showcase task task generateModels { doLast { // The most complex solution, you could configure the client as you want // i.e. set preview API key DeliveryOptions options = new DeliveryOptions(); options.setProjectId("975bf280-fd91-488c-994c-2f04416e5ee3"); DeliveryClient client = new DeliveryClient(options); CodeGenerator generator = new CodeGenerator( options.getProjectId(), 'com.kentico.kontent.test.springapp.models', file('src/main/java') ); List<JavaFile> sources = generator.generateSources(client); generator.writeSources(sources); } } // Runs generateModels task ./gradlew generateModels
    • shell
    kontent-generate --projectId=8d20758c-d74c-4f59-ae04-ee928c0816b7 --codeType=JavaScript --moduleResolution=ES2015
    kontent-generate --projectId=8d20758c-d74c-4f59-ae04-ee928c0816b7 --codeType=JavaScript --moduleResolution=ES2015
    • shell
    dotnet tool install -g Kentico.Kontent.ModelGenerator dotnet tool run KontentModelGenerator --projectid 8d20758c-d74c-4f59-ae04-ee928c0816b7 --withtypeprovider true --structuredmodel true
    dotnet tool install -g Kentico.Kontent.ModelGenerator dotnet tool run KontentModelGenerator --projectid 8d20758c-d74c-4f59-ae04-ee928c0816b7 --withtypeprovider true --structuredmodel true
    • shell
    kontent-generate --projectId=8d20758c-d74c-4f59-ae04-ee928c0816b7 --codeType=TypeScript --moduleResolution=ES2015
    kontent-generate --projectId=8d20758c-d74c-4f59-ae04-ee928c0816b7 --codeType=TypeScript --moduleResolution=ES2015

    Retrieve strongly typed content

    With your models defined and included in your application, you can use them when retrieving items from Kontent.

    • Java
    // Tip: Find more about Java SDK at https://docs.kontent.ai/java import kentico.kontent.delivery.*; import java.lang.System; // Gets a content item from Kentico Kontent by its codename and maps it to its strongly typed model DeliveryClient client = new DeliveryClient("8d20758c-d74c-4f59-ae04-ee928c0816b7"); CompletionStage<Homepage> homepageResult = client.getItem("hello_caas_world", Homepage.class); // Use homepageResult // homepageResult.thenAccept(homepage -> System.out.println(homepage.getHeadline())
    // Tip: Find more about Java SDK at https://docs.kontent.ai/java import kentico.kontent.delivery.*; import java.lang.System; // Gets a content item from Kentico Kontent by its codename and maps it to its strongly typed model DeliveryClient client = new DeliveryClient("8d20758c-d74c-4f59-ae04-ee928c0816b7"); CompletionStage<Homepage> homepageResult = client.getItem("hello_caas_world", Homepage.class); // Use homepageResult // homepageResult.thenAccept(homepage -> System.out.println(homepage.getHeadline())
    • C#
    // Tip: Find more about .NET SDKs at https://docs.kontent.ai/net using Kentico.Kontent.Delivery; using KenticoKontentModels; // Creates an instance of the delivery client // ProTip: Use DI for this in your apps https://docs.kontent.ai/net-register-client IDeliveryClient client = DeliveryClientBuilder .WithProjectId("8d20758c-d74c-4f59-ae04-ee928c0816b7") .Build(); // Gets a content item by codename and maps it to the item's strongly typed model IDeliveryItemResponse<Homepage> response = await client.GetItemAsync<Homepage>("hello_caas_world"); var homepage = response.Item; // Use homepage // Console.WriteLine(homepage.Headline);
    // Tip: Find more about .NET SDKs at https://docs.kontent.ai/net using Kentico.Kontent.Delivery; using KenticoKontentModels; // Creates an instance of the delivery client // ProTip: Use DI for this in your apps https://docs.kontent.ai/net-register-client IDeliveryClient client = DeliveryClientBuilder .WithProjectId("8d20758c-d74c-4f59-ae04-ee928c0816b7") .Build(); // Gets a content item by codename and maps it to the item's strongly typed model IDeliveryItemResponse<Homepage> response = await client.GetItemAsync<Homepage>("hello_caas_world"); var homepage = response.Item; // Use homepage // Console.WriteLine(homepage.Headline);
    • TypeScript
    // Tip: Find more about JS/TS SDKs at https://docs.kontent.ai/javascript import { ContentItem, DeliveryClient, Elements, SortOrder, TypeResolver } from '@kentico/kontent-delivery'; import { Homepage } from './models/homepage'; // Creates an instance of the Delivery client and registers your model in type resolvers const deliveryClient = new DeliveryClient({ projectId: '8d20758c-d74c-4f59-ae04-ee928c0816b7', typeResolvers: [ new TypeResolver('homepage', (rawData) => new Homepage) ] }); var homepage: Homepage; // Gets a content item from Kentico Kontent by its codename and maps it to its strongly typed model deliveryClient.item<Homepage>('hello_caas_world') .toObservable() .subscribe(response => { homepage = response.item; // Use homepage; // console.log(homepage.headline.value); });
    // Tip: Find more about JS/TS SDKs at https://docs.kontent.ai/javascript import { ContentItem, DeliveryClient, Elements, SortOrder, TypeResolver } from '@kentico/kontent-delivery'; import { Homepage } from './models/homepage'; // Creates an instance of the Delivery client and registers your model in type resolvers const deliveryClient = new DeliveryClient({ projectId: '8d20758c-d74c-4f59-ae04-ee928c0816b7', typeResolvers: [ new TypeResolver('homepage', (rawData) => new Homepage) ] }); var homepage: Homepage; // Gets a content item from Kentico Kontent by its codename and maps it to its strongly typed model deliveryClient.item<Homepage>('hello_caas_world') .toObservable() .subscribe(response => { homepage = response.item; // Use homepage; // console.log(homepage.headline.value); });

    A complete example

    This code example is equivalent to the first one but maps the retrieved content item to a strongly typed model.

    What's next?

    In practice, you'll often have to define how your application resolves rich text elements containing assets, links, components, and other content items. This works a little differently for each platform, so we recommend that you have a look at the documentation of the SDK you are using:

    For more advanced examples of using strongly typed models, see our sample applications.