1

We have a new GET service endpoint which expects DateTime and Decimal data, among other parameters. For simplicity, this represent our request without any fix yet:

        app.MapGet("saleEvent", async (string amount, string date) =>
        {
            long.TryParse(amount, out var requestAmount);  //Use *culture* parameter
            DateTime.TryParse(date, out var requestDate);  //Use *culture* parameter
            await DoSomething(requestAmount, requestDate);
        });

We are receiving the data as strings, because a couple of our customers are based in different countries, with different formats, according to their culture.

We want to ask the customer to send their culture somewhere in the request, in order to be able to properly process the received data.

Well, here we have found many alternatives for our customers to include in their request, but I'm not sure which is the best or proper fit to do this:

accept-language header: Seems to indicate which culture they expect in the response, nothing to do with the parameters. Not our case as our response is just 200 (OK).

content-language header: Seems to indicate the language of the body. As we are not receiving a body, but a query string, I doubt we should use it.

One additional parameter in the query, like:

        app.MapGet("saleEvent", async (string date, string amount, string culture)

A custom header for the same purpose.

Other recommendation was to receive the Date as UTC+0, but I think the customer should not be worried with removing the offset thing.

Is there any standar way to do this?

zameb
  • 705
  • 11
  • 26
  • Just to add a possible alternative: Let your API work with DateTime and Decimal, and make it the client's (i.e., the UI's) responsibility to parse the data. Since many other localization/globalization issues need to be handled by the UI layer anyways, why not handle them all in the UI layer instead of separating them between UI and business logic layer? – Heinzi Feb 08 '22 at 13:47
  • 1
    You expect the client to competently be able to deliver culture information and for both sides to be in agreement on what a culture *means* but you don't trust the client to do the conversions? That seems odd. If I'm told an API expects datetime information in [ISO8601 format](https://en.wikipedia.org/wiki/ISO_8601), an international standard, I'm not terribly surprised by the requirement. – Damien_The_Unbeliever Feb 08 '22 at 13:47
  • @Damien_The_Unbeliever, I don't think its odd. If the customer needs to report data, they are sure that their culture is the *right* one. Probably the server culture is not even a common one. Or we can move the server to a different culture any time – zameb Feb 08 '22 at 13:51
  • @zameb it's *very* odd. There's an actual standard for dates in JSON - [RFC7493](https://datatracker.ietf.org/doc/html/rfc7493#section-4.3) specifies that dates should be in ISO8601. `It is RECOMMENDED that all such data items be expressed as string values in ISO 8601 format`. All HTTP APIs use that format for over a decade now, even before the RFC was proposed. Change the date type to `DateTimeInfo` from `DateTime` so you can handle the actual values posted by clients – Panagiotis Kanavos Feb 08 '22 at 13:53
  • @Damien_The_Unbeliever, yes I think is a good solution and we are considering to use the ISO 8601. But, in the case of decimals, we still need to deal with comma or dot for the decimal part. What should we recommend for the decimal? – zameb Feb 08 '22 at 13:58
  • No you don't. The decimal format was always part of the JSON specification. There's absolutely no ambiguity there. Frankly, what's the actual problem? All clients will serialize to JSON the same way. If you use [JSON.stringify()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) in JavaScript you'll get numbers with dots and dates in ISO8601. – Panagiotis Kanavos Feb 08 '22 at 13:58

1 Answers1

3

We have a new GET service endpoint which expects DateTime and Decimal data,

No, you don't. Just correct your endpoint:

app.MapGet("saleEvent", async (decimal amount, DateTime date) =>

There you go. Since this endpoint is called by another computer program, it is that programs' job to make sure their user input is correctly transferred into those datatypes. Who knows if they even have user input. That program might read it from a file or database, too.

C# is a strongly typed language. Don't transform it into a stringly typed language by using coding anti-patterns.

nvoigt
  • 75,013
  • 26
  • 93
  • 142
  • Besides, someone would have to go out of their way to serialize dates and decimals the wrong way. The format for decimals and since 2015, dates, is standardized. – Panagiotis Kanavos Feb 08 '22 at 14:03
  • 1
    The intention on the question is, *precisely*, to remove any anti-pattern. We'll proceed this way – zameb Feb 08 '22 at 14:15