haimkastner / unitsnet-js

A better way to hold unit variables and easily convert to the destination unit
https://www.npmjs.com/package/unitsnet-js
MIT License
23 stars 8 forks source link

Support Cross-Technologies Unit & API Specifications #31

Closed haimkastner closed 5 months ago

haimkastner commented 6 months ago

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

The API object should look similar to:

export interface LengthDto {
    value: number;
    unit: LengthUnits;
}

And this is also how it will be represented in the OpenAPI specification.

The JSON will look like this:

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

As part of the full JSON payload something like:

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

Any unit class will have an API to expose and load it:

export interface LengthDto {
    value: number;
    unit: LengthUnits;
}

export  class Length {

  ...
  ...

  public toDto(holdInUnit: LengthUnits = LengthUnits.Meters): LengthDto {
        return {
            value: this.convert(holdInUnit),
            unit: holdInUnit
        } ;
    }

    public static fromDto(dtoLength: LengthDto): Length {
        return new Length(dtoLength.value, dtoLength.unit);
    }
}

See also #29 for motivation

Shentoza commented 6 months ago

that would be a great change, currently we're holding a custom LengthDto that allows us to parse to/from out c# unitsnet backend.

const LengthToString = (input: { value: number; unit: string }): string => {
  const unit = getLengthUnit(input.unit);
  const l = new Length(input.value, getLengthUnit(input.unit));
  return l.toString(unit);
};

the one usage we're currently not doing is actually converting the data from the backend to a UnitsNetJS Length, since it's hard to map the "Meter" string coming from the backend to the actual enum value.

Currenlty (as far as I see it) a UnitsNetJS Length has no information about the unit it currently is representing, since it always has Meter as a base.

haimkastner commented 6 months ago

@Shentoza
In your time you can see my new PR #32 with an implementation of this and check it that can improve your use-cases.

In the meantime, I have opened a discussion angularsen/UnitsNet#1378 with the UnitsNet owner to see his opinion about such a cross-language convention.

Shentoza commented 6 months ago

That's awesome. The example implementation in C# is basically what we're currently doing, to support a readable API response from our backend. Once your PR completes, we can remove all the bandaid solutions and almost feel like we're using a cross-technology framework for unit handling

haimkastner commented 5 months ago

Implemented by #32

haimkastner commented 5 months ago

@Shentoza After ~ two months of waiting for progress on the UnitNet library discussion, I've decided to merge the changes into the main version. From now on, you can utilize this updated version from both JS #32 & Python (haimkastner/unitsnet-py#18)

Regardless of the final decision made in the UnitNet thread, I'll maintain backward compatibility with this merged API.