Hacker News new | past | comments | ask | show | jobs | submit login

You presume that the program is able to determine that it is wrong.

One of the most annoying things moving from Ruby / Python into a language with static types that are checked at compile time is dealing with JSON from an external API.

I know, I know. The API could send me back a lone unicode snowman in the body of the response even if the Content-Type is set to JSON. I know that is theoretically possible.

But practically, the endpoint is going to send me back a moustache bracket blob. The "id" element is going to be an integer. The "first name" element is going to be a string.

Sometimes a disable-able warning is all we want.




Maybe look at languages created in the last 30 years or so?

Because e.g. in Rust what you're talking about is:

    #[derive(Deserialize)]
    struct Whatever {
        id: usize,
        first_name: String
    }

    // ...

    let thing: Whatever = get(some_url)?.json()?;
You encode your assumptions as a structure, then you do your call, ask for the conversion, get notified that that can fail (and you can get an error if you but ask), and then you get your value knowing your assumptions have been confirmed.

It's definitely less "throw at the wall" than just

    thing = get(some_url).json()
but it's a lot easier to manipulate, inspect, and debug when it invariably goes to shit because some of your assumptions were wrong (turns out `first_name` can be both missing and null, for different reasons).

For a 5 lines throwaway script the latter is fine, but if it's going to run more than a pair of time or need more than few dozen minutes (to write or run) I've always been happier with the former, the cycle of "edit, make a typo, breaks at runtime, fix that, an other typo, breaks again, run for an hour, blow up because of a typo in the reporting so you get jack shit so you get to run it again".


I haven't had problems with that in strongly-typed languages I've used (most notably, C#). If the response payload isn't JSON, or if it has a missing required field or something is the wrong type, then JsonSerializer.Deserialize(...) will throw an exception. I don't have to add more code just to make the type check pass or anything. (And if I did, _usually_ it's around nullability and the "!" operator would do the trick, or "?? throw new ImpossibleException(...)")

And within the bounds of pragmatism, it's nice that it actually checks this stuff and throws exceptions. In Ruby if the ID field is the wrong type, the exception won't happen at time of JSON.parse(...) but instead much later when you go to use the parsed result. Probably leading to more confusion, and definitely making it harder to find that it was specifically an issue with the JSON and not with your code.


"One of the most annoying things moving from Ruby / Python into a language with static types that are checked at compile time is dealing with JSON from an external API."

That doesn't make much sense - either the API has a well-defined schema, and you define your static types to match (which there are usually tools to do for you automatically, based on an OpenXML/Swagger schema, if there isn't already an SDK provided in your language of choice), or you use a type designed for holding more arbitrary data structures (e.g. a simple string->object Dictionary, or some sort of dedicated JsonObject or JsonArray type).

There are issues around JSON and static typing, e.g. should you treat JSON with extra fields as an error, date/time handling, how to represent missing values etc. (and whether missing is semantically different to null or even undefined), but I would hardly see it as "one of the most annoying things".

Edit: the other issue I forgot is JSON with field names that aren't valid identifiers, e.g. starting with numerals or containing spaces or periods etc. But again, not insurmountable. I'd actually be in favour of more restrictive variation of JSON that was better geared towards mapping onto static types in common languages.


Oh, sweet summer child. If only those ‘shoulds’ would reliably be ‘will’s, the world would be a much better place.


TypeScript can type based on object literals, so while you can't type JSON on the fly, you can type a JSON file automatically.

With code gen you can usually just print out your JSON directly from the source and import that as a type into your source code.

This is why apis are moving towards specifications that trigger multiple generators.

JSON typing is possible without generation, but more cumbersome.

interface TypedJSON {

  string?: string;

  number?: number;

  array?: TypedJSON[];

  boolean?: boolean;

  object?: {[key: string]: TypedJSON}
}

{foo: {string: "my string"}, bar: {number: 4}}

Probably makes sense to make the "string" key "s" for minimal payload size impact, or this could also be done by converting standard JSON to this typed representation at runtime.


You should check what the external API returns anyway. If only because the format of any external API might break in subtler way than just returning a single Unicode snowman, and you'll want to ensure that all such failures are correctly detected as soon as practically feasible.




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: