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

> Lack of a Map-type.

Why do you need special map types for transferring maps? Doesn't list of key-value pairs suffice?

Also, why am I wrong to even ask the above questions?




It's a fair question. Having a map-type has several benefits:

1. I can signal to my api's users that there won't be any repeating keys without having to write documentation

2. The type can be mapped correctly into the target language. Most languages have a map-type and so it's nice if you don't have to convert it yourself

3. No manual conversion also saves time in most cases, since libraries can do it efficiently in one step. Otherwise you get a list<X> from your library and have to turn it into a map. Not good for bigger lists in performance sensitive applications

4. The same is also true the other way around when sending data to the server

5. It saves space in many serialization formats like json. Instead of [{"key": "key1", value: "value1"}, ...] you get {"key1": "value1", ...}

6. It's nicer to read and debug

7. It's nicer to manually create/write those values in tools like graphiql to test queries by hand and those tools can even warn you if you repeat a key by accident

Just some of the things out of my head, I'm sure I've missed a bunch.


1. Pretty much that's the answer I was looking for.

...

5. I thought about something like [["key1", "value1"], ["... like in Lisp-y languages.


Yes (5.) is possible, but now your API type becomes "List of List of String" and you need documentation and examples to explain that every list will have two entries and the first one will be the key. On top of that, if you have a different types for keys and values you have an even bigger problem, because lists in graphql need to have one type for all elements.

And while you can use a uniontype (like String | Integer) to have strings as keys and integers as values, your user now ends up with an ugly typ in their code and has to untangle it by hand.

So the user will have to 1.) know about that it is supposed to be a map, 2.) untangle the list types in their code, 3.) convert it into a map while not mixing up key and value

Therefore I usually go with explicit key/value objects if it's okay for performance or go with a custom JSON type if performance trumps the rest.


I see, GraphQL definitely needs maps and tuples then.


I created a proposal for Map type but didn’t make it through.

https://github.com/graphql/graphql-spec/pull/888

The issue with GraphQL is it tries to appease too many masters.

Similar to jsx. The language isn’t evolving.

The good thing is the spec is (almost) frozen, so there’s many implementations, the bad is it can’t encompass the flexibility of json schema can do.

Going with GraphQL means you have to have good control over both client and server. And like any tool, there are new ways to shoot yourself.


A (single-level) Map is generally understood to have unique keys, which allows for some invariants derived from this property, such as a one-to-one or one-to-many object relationship, without runtime checks in client code.

I do think it's worthwhile to ask the question, though. I have a strong personal preference to avoid encoding invariants like this in wire representations, because they are properties of the _schema_ and not the wire type (JSON object, in my most commonly-encountered case).

Of course, the entire point of GraphQL is to encode invariants in the data schema, so it's entirely reasonable to ask for a built-in Map type instead of building your own for every project.


JSON (as defined by json.org), for example, does not specify that key/value pairs need to be unique. ECMA-404 explicitly calls this out as an implementation consideration. I know of one implementation that supports multiple entries with the same key.




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: