Closed haimkastner closed 1 month ago
Super late reply, sorry.
This is a good initiative, but I'm a bit hesitant to own the serialization and OpenAPI schema for this.
Luminosity.Watt
and Power.Watt
. See wiki for example JSON.I mean, yes, we can probably land on an OpenAPI schema and store it in this repo to make it "official", as long as we don't handle migration of serialized data between major versions.
However, you would be the main driver for this project so it could also make sense for the OpenAPI schema to live in your github and we just refer to it in the readme. What do you think?
By the way, at work, we have some extensions for the swagger builder that help us generate a fully specified swagger.json
for the APIs that have quantities in the contract (at least for the AbbreviatedJsonConverter
).
My colleague was supposed to create a PR (or at least a discussion) for it (I assume that would be an independent nuget).
Let's see if this would paste (I'm copying from the swagger UI):
MolarMass UnitsNet.MolarMass{ description:
Example: 1 kg/mol (Unit: KilogramPerMole, Dimensions: [Mass][Amount]). Click here to learn more. Value* number($double) example: 1 The quantity value (in the specified unit)
Unit* string($enum) example: kg/mol The quantity unit represented by it's default abbreviation Enum: [ cg/mol, dag/mol, dg/mol, g/mol, hg/mol, kg/mol, klb/mol, Mlb/mol, µg/mol, mg/mol, ng/mol, lb/mol, kg/kmol ]
Type* string($enum) default: MolarMass The quantity type discriminator }
Maybe I'm misreading this, but I'm not sure it's a good idea to use abbreviations as the enum value.
Abbreviations have historically seen a lot of breaking changes (renames, fixing syntax, disambiguating imperial/US units, or using a more common form as the primary abbreviation). More so than the unit enum names, although these change too.
Also, how does generating C# code for an OpenAPI spec with enum values like cg/mol
work? Does it automatically set up JSON converters to map the strings?
It's not really an Enum, those are still strings, but the declaration- string(enum) lists the available options- which is very helpful (and also fill's in the contracts examples).
{
"Category": "string",
"Diameter": {
"Value": 1,
"Unit": "m",
"Type": "Length"
},
"Height": {
"Value": 1,
"Unit": "m",
"Type": "Length"
},
"Weight": {
"Value": 1,
"Unit": "kg",
"Type": "Mass"
},
"Option": "string",
"Material": "string",
"Name": "string",
"Volume": {
"Value": 1,
"Unit": "m³",
"Type": "Volume"
},
"ID": 0
}
As for the contract itself- It's every API's choice, I think there is a very strong argument to be made for the use of the abbreviations- when the client side isn't a .net application (like in my case). So basically, the API declares what inputs it supports, which is completely independent of what is the latest version of Units.Net..
Thanks for your reply!
What I'm trying to solve, is not how to serialize units into DB, files, or any permanent storage, I'm trying to solve unit transfer between systems and microservices.
Let's say I have C# and Python services in my backend and JS frontend, which communicate via Rest/GraphQL. Instead of converting any unit representation to a particular quantity (Meter, Centimeter, etc.) in the Rest/GraphQL schemas and making sure both sender and receiver services are aligned to do the right particular quantity from/to conversion.
With UnitsNet, all services can use the UnitsNet library, represent the unit DTO (Length DTO, Angle DTO, etc.) in the schema (whether using OpenAPI/similar tools or not), and send/load the data without conversion of quantity, just call to/from DTO in any service in the system.
To allow that easily, I suggest adding DTO interface representation and to/from DTO methods to each unit.
- We make breaking changes all the time; renaming/removing quantities and units. Handling this 100% for serialized data can be painful, so up until now this has been the application developer's responsibility.
I agree, but since I'm trying to solve only the communication process, I think it's reasonable to limit the communication between the services only if all of them are in the same major version. This means that if the developer decides to update UnitsNet, needs to update the ALL UnitsNet libraries in all services to the latest.
From my side, regardless of this topic, I will make sure that any new major version in this project, will be reflected to a new major version in the JS and PY flavors as well haimkastner/unitsnet-js#45.
2. The OpenAPI schema should include information about the quantity type to disambiguate, since there are several quantities that share unit names, such as
Luminosity.Watt
andPower.Watt
. See wiki for example JSON.
You are right, I will add the unit type (Power / Luminosity) as well like this:
{
"value":100.01,
"quantity":"Meter",
"unit": "Length"
}
haimkastner/unitsnet-js#46
However, as a side note, I think that for most of the use cases, the send and the receiver services know the Unit, and I'm trying only to save them from converting back and forth the quantity, so once the service knows let's say that it's a Power
unit, we don't care that Luminosity
has also Watt
is his quantities.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.
This issue was automatically closed due to inactivity.
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:
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:
As part of the full JSON API payload something like:
See an OpenAPI unitsnet-openapi-spec example schema.
A basic and naive prototype of how it will be in C#
A similar implementation I have created for the JS package haimkastner/unitsnet-js#32 & haimkastner/unitsnet-py#18
TypeScript usage (docs)
Similar for the Python package (docs):
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