Cloud and Software Architecture, Soft skills, IOT and embedded
Creating Immutable Functional Style Dart Model Objects based on JSON or JSON schemas
Get link
Facebook
X
Pinterest
Email
Other Apps
Flutter is opinionated about using a functional programming model that includes immutable data objects. I've found that we tend to ignore that whole immutable thing when dealing with JSON data.
Projects can be loose when handling incoming JSON data and how it is accessed, sprinkling string-style map keys across the codebase. We can reduce that tendency by providing models to eliminate the string keys and mutable models to stop people from directly manipulating maps of strings.
Some languages are functional only. Other languages have no way of generating immutable objects. In those cases, we just end up with objects that can be easily converted into and out of JSON structures and strings.
I'm working in Dart right now so the rest of this will be Dart samples
Modeling Longitude and Latitude Using the JSON Schema
Let's pick something simple as an example. We're going to use this Latitude and Longitude JSON Schema that follows the schema definition style from http://json-schema.org/draft-06/schema#. A coordinate on the earth's surface is represented by a longitude and a latitude.
Making the objects immutable, unchangeable after creation.
We want to operate in a Functional Programming model with immutable objects. Enabling Make all properties required and Make all properties final results in. Note the added final and required.
classCoordinate {
finaldoublelatitude;
finaldoublelongitude;
Coordinate({
requiredthis.latitude,
requiredthis.longitude,
});
}
Simplify creating mutated copies of the data.
Information changes. This means we need a way of creating new model objects that have one or more property differences from the object they were created from.
We want to make it easy on the programmer so we enable Generate CopyWiththat creates a new instance by making a copy with the requested changes applied. Note the added CopyWith()method.
classCoordinate {
finaldoublelatitude;
finaldoublelongitude;
Coordinate({
requiredthis.latitude,
requiredthis.longitude,
});
CoordinatecopyWith({
double?latitude,
double?longitude,
}) =>
Coordinate(
latitude:latitude??this.latitude,
longitude:longitude??this.longitude,
);
}
We're all about serializing and deserializing our model with JSON
The next step is to add JSON serialization and deserialization support. quicktype can generate global functions or static methods on the class. I'm a classy sort of person so I'll do the latter by turning off the Types onlyselector. We get a class that can
Create a model instance from a JSON string.
Create a model instance from a Map<String, dynamic>
Create a JSON data structure from a model object instance.
Create a JSON string from a model object instance.
Real-world JSON schemas and modeling are a lot more complicated than this simple example. There are a variety of tools out there. At the time of this article, I'd recommend exploring JSON modeling including functional programming if your language supports it. I used https://app.quicktype.io but there are other tools out there.
I do a lot of my development and configuration via ssh into my Raspberry Pi Zero over the RNDIS connection. Some models of the Raspberry PIs can be configured with gadget drivers that let the Raspberry pi emulate different devices when plugged into computers via USB. My favorite gadget is the network profile that makes a Raspberry Pi look like an RNDIS-attached network device. All types of network services travel over an RNDIS device without knowing it is a USB hardware connection. A Raspberry Pi shows up as a Remote NDIS (RNDIS) device when you plug the Pi into a PC or Mac via a USB cable. The gadget in the Windows Device Manager picture shows this RNDIS Gadget connectivity between a Windows machine and a Raspberry Pi. The Problem Windows 11 and Windows 10 no longer auto-installs the RNDIS driver that makes magic happen. Windows recognizes that the Raspberry Pi is some type of generic USB COM device. Manually running W indows Update or Update Driver does not install the RNDI
The Windows Subsystem for Linux operates as a virtual machine that can dynamically grow the amount of RAM to a maximum set at startup time. Microsoft sets a default maximum RAM available to 50% of the physical memory and a swap-space that is 1/4 of the maximum WSL RAM. You can scale those numbers up or down to allocate more or less RAM to the Linux instance. The first drawing shows the default WSL memory and swap space sizing. The images below show a developer machine that is running a dev environment in WSL2 and Docker Desktop. Docker Desktop has two of its own WSL modules that need to be accounted for. You can see that the memory would actually be oversubscribed, 3 x 50% if every VM used its maximum memory. The actual amount of memory used is significantly smaller allowing every piece to fit. Click to Enlarge The second drawing shows the memory allocation on my 64GB laptop. WSL Linux defaults to a maximum RAM size of 5
The Apache Tika project provides a library capable of parsing and extracting data and meta data from over 1000 file types. Tika is available as a single jar file that can be included inside applications or as a deployable jar file that runs Tika as a standalone service. This blog describes deploying the Tika jar as an auto-scale service in Amazon AWS Elastic Beanstalk. I selected Elastic Beanstalk because it supports jar based deployments without any real Infrastructure configuration. Elastic Beanstalk auto-scale should take care of scaling up and down for for the number of requests you get. Tika parses documents and extracts their text completely in memory. Tika was deployed for this blog using EC2 t2.micro instances available in the AWS free tier. t2.micro VMs are 1GB which means that you are restricted in document complexity and size. You would size your instances appropriately for your largest documents. Preconditions An AWS account. AWS access id and secret key.
Comments
Post a Comment