Skip to content

Support Cross-Technologies DTO & API Specifications #1378

Closed
@haimkastner

Description

@haimkastner

Is your feature request related to a problem? Please describe.

Request related

As part of the powerful and wide support in multiple languages in the unit definition, I think it can be cool to standardize the way how unit is represented in the API spec, and how it will be exposed/loaded.

Implementing in all UnitsNet-based libraries a similar API DTO to load/expose and the same JSON schema standard of how the unit is represented, will give the benefits of:

  1. Work with UnitsNet across various technologies transparently without any kind of manual conversions.
  2. Standart way how to represent units in API schemas.
  3. Clear OpenAPI specification (and automatically in case the spec is generated from the code object declarations)
  4. Human readable unit representation in the API schema, and easy to work with anyway.

See also haimkastner/unitsnet-js#29 for real-world, probably common use-case between C# backend and TypeScript frontend.

Currently, sterilizing is supported in the library, but not as a common, standard, unit dedicated and easy-to-use API.

Describe the solution you'd like

The JSON standart DTO will look like this:

{
   "value":100.01,
   "unit":"Meter"
}

As part of the full JSON API payload something like:

{
   "someInfo":"someValue",
   "someInfoLength":{
      "value":100.01,
      "unit":"Meter"
   }
}

See an OpenAPI unitsnet-openapi-spec example schema.

A basic and naive prototype of how it will be in C#

using System;
using UnitsNet;
using UnitsNet.Units;
using System.Text.Json;

public class LengthDto
{
	class JsonDto
	{
    	public double value { get; set; }
    	public string unit { get; set; }
	}
	
    public LengthDto(double value, LengthUnit unit)
    {
        this.value = value;
        this.unit = unit;
    }
	
    public double value { get; set; }
    public LengthUnit unit { get; set; }
	
	public string ToJson()
    {
		JsonDto jsonInterface = new JsonDto { value = this.value, unit = this.unit.ToString() };
		return JsonSerializer.Serialize(jsonInterface);
    }
	
	public static LengthDto fromJson(string json)
    {
		JsonDto jsonInterface = JsonSerializer.Deserialize<JsonDto>(json);
		Enum.TryParse<LengthUnit>(jsonInterface.unit, out LengthUnit newUnit);
		return new LengthDto(jsonInterface.value, newUnit);
    }
}


public static class LengthExtensions
{
    public static Length fromDto(this Length length, LengthDto lengthDto) 
    {
       return new Length(lengthDto.value, lengthDto.unit);
    }
	
	public static LengthDto toDto(this Length length, LengthUnit unit = LengthUnit.Meter) 
    {
       return new LengthDto(length.As(LengthUnit.Meter), unit);
    }
}

public class Program
{
	public static void Main()
	{
		Length lengthValue = Length.FromMeters(100.01);
		string json = lengthValue.toDto().ToJson();
		Console.WriteLine(json); // {"value":100.01,"unit":"Meter"}
		
		LengthDto newLengthDto = LengthDto.fromJson(json);
		Length newLengthValue = new Length().fromDto(newLengthDto);
		Console.WriteLine(newLengthValue.Meters); // 100.01
	}
}

A similar implementation I have created for the JS package haimkastner/unitsnet-js#32 & haimkastner/unitsnet-py#18

TypeScript usage (docs)

// Create a Length unit object
const length = Length.FromMeters(100.01);
// Obtain the DTO object, represented by the default unit - meter
const lengthDto: LengthDto = length.toDto(); // {"value":100.01,"unit":"Meter"}
// Obtain Length object from lengthDto
const newLength: Length = Length.FromDto(lengthDto);

Similar for the Python package (docs):

 # Create a Length unit object
length = Length.from_meters(100.01)
# Obtain the DTO object as json, represented by the default unit - meter
length_dto_json = length.to_dto_json() # {"value":100.01,"unit":"Meter"}
# Load JSON to DTO, and load
length_from_dto = Length.from_dto_json(length_dto_json)

Describe alternatives you've considered
To do it manually.

Additional context

See an example of the Python Length implementation of the DTO class and the unit API example

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions