Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Generating Web Application Code from JSON Sample Data

4.11/5 (5 votes)
9 Aug 2021CPOL3 min read 8K  
A code generator that helps you create ASP.NET 5 and Vue 3 applications much faster
In this post, you will find an introduction to the internal workings of BootGen, the code generator that can create ASP.NET 5 and Vue 3 application based on a JSON data set.

Introduction

JavaScript
{
  "users": [
    {
      "userName": "Jon",
      "email": "jon@arbuckle.com",
      "pets": [
        {
          "name": "Garfield",
          "species": "cat"
        },
        {
          "name": "Odie",
          "species": "dog"
        }
      ]
    }
  ]
}

Imagine that you are starting to write a web application for pet owners. The piece of JSON code above is your initial data set. How do you start it? Before you can start implementing the hot features you have imagined for this project, there is some groundwork to be done first.

For the database, you will need two tables, users and pets. You will need a seed that fills up your database with the initial dataset. For the backend, you will need data services and controllers for the user and the pet class. For the frontend, you will need a REST API client and state management. Some basic viewer and editor will also surely come in handy. Oh, and do not forget the authentication!

Now that you are done with all these, you can start working on the meaningful part. But how much work does this "groundwork" take? Well, if your chosen stack is ASP.NET 5 with Vue 3 and TypeScript, it will be 1677 lines of code in 26 files. This amount of code does not include the empty project created with the dotnet new and the vue create commands.

The goal of the BootGen project is to take a JSON dataset and generate the groundwork for your project, saving you hours or even days of work.

You can already try this at bootgen.com!

How Does It Work?

The point of this article is to discuss how BootGen works under the hood. It is not necessary to understand this if you only wish to use the tool and enjoy the freed-up time. But those who would like to gain a deeper understanding, please stay with me.

Creating the Data Model

There are two important steps in the generation process. First, a data model should be built based on the data set. The following classes can be used to create the data model.

C#
public class ClassModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Property> Properties { get; }
}

public class Property
{
    public string Name { get; set; }
    public BuiltInType BuiltInType { get; set; }
    public bool IsCollection { get; set; }
    public ClassModel Class { get; set; }
}

public enum BuiltInType { String, Int, Float, Bool, DateTime, Object }

These are simplified from what we actually use in the SDK. If you are interested in the complete meta-model, you can find it at https://github.com/BootGen/BootGenSDK.

The names of the classes can be easily inferred from the JSON property names if we assume that the collection names are always in the plural form and everything else is always in the singular form. Pluralize.NET enables us to conveniently find the plural or the singular form of a particular word.

For each JSON property, we will create a property in our model. If it has a primitive type (string, integer, float, boolean, or date-time), then we are done in one step. However, if it is an object, then we continue recursively: we will check if a class model with the same name already exists. If yes, we will extend it, if not, then we create a new one.

Rendering the Code

To render the code, we use a templating language called Scriban. The simplest template that generates a C# entity class would look like this:

C#
public class {{ class.name }}
{
    {{~ for property in class.properties ~}}
    public {{ get_type property }} {{ property.name }} { get; set; }
    {{~ end ~}}
}

The class variable refers to an object of ClassModel type. In Scriban, every property and function name is converted to snake case. The get_type is a function call that is implemented in C# and looks like this:

C#
public static string GetType(Property property)
{
   string baseType = GetBaseType(property);
   if (property.IsCollection)
       return $"List<{baseType}>";
   return baseType;
}

public static string GetBaseType(Property property)
{
   switch (property.BuiltInType)
   {
       case BuiltInType.Bool:
           return "bool";
       case BuiltInType.Float:
           return "float";
       case BuiltInType.String:
           return "string";
       case BuiltInType.DateTime:
           return "DateTime";
       case BuiltInType.Object:
           return property.Class.Name;
       default:
           return "int";
   }
}

When generating TypeScript code, a different GetType function is used.

Project Structure

BootGen SDK

This is the core library that handles building the data model from the JSON input and rendering the Scriban templates.

Framework Plugins

The support for different frameworks is implemented as plugins. Currently, the following plugins are implemented:

A framework plugin contains:

  • a bunch of Scriban templates
  • some static files (basically an empty project for the given framework)
  • a configuration file

We do our best to keep the plugin interface clean, to make it easy to implement support for other frameworks in the future.

Web Application

This is the web application deployed to bootgen.com. A convenient way to use BootGen.

History

  • 9th August 2021: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)