3 ms·
`map[string]interface{}` screams disconnected from reality when building web software. What an awful experience.
by andrewmcwatters 5y ago
`map[string]interface{}` screams disconnected from reality when building web software. What an awful experience.
- deleted 5y ago[deleted]
- tptacek 5y agoI only rarely ever use `interface{}` anywhere in Go code. The idiomatic thing to do with JSON messages you're going to hold onto in Go web code is to type them, just as you would in Rust with serde.
- andrewmcwatters 5y agoYeah, nah. I’m not typing 5 levels of “structs” for one or two properties I want.
- nkozyra 5y agoYeah, the formality of embedded structs can lead to some very verbose bloat. And it obviously only works on very reliable payloads.
- tptacek 5y agoWhat's the solution for an unreliable payload? When things aren't where you expect them in a JSON blob with a Python Flask app, your app also just breaks on that input.
- tgsovlerkhgsel 5y agotry: val = input['foo']['bar'] except KeyError, TypeError: raise HttpErrors.BadRequest
- Kocrachon 5y agoCan someone explain to me why python uses try/except so often? I see that promoted as a solution instead of; if 'bar' in input['foo'].keys(): val = input['foo']['bar'] Generally, exceptions cause code to run slower and I feel like in any other language is considered bad practices. I never understood why Python promotes EAFP vs LBYL. Both performance and accuracy wise, checking before doing is safer and faster performance.
- tgsovlerkhgsel 5y agoYour example will throw a KeyError if "input" doesn't contain "foo", and an AttributeError if "foo" is some unexpected data type that doesn't have keys().
- kortex 5y agoWell, firstly input.get("foo", {}).get("bar", default) is a bit nicer, imho. Python exceptions are only slower on the exception. They are almost exactly the same speed on success. LBYL forces you to look for all the ways in which you might leap. EAFP lets you handle even unexpected conditions. The classic use case is checking if a condition exists, then doing the thing, except the condition changed between check and run. So you gotta catch anyways. I've been moving away from this actually and towards a rust-like Result[T, Exception]. I'm using the package called "result". For fastapi api_request -> handler -> some_func_chain -> return response_to_client patterns, if something barfs, you normally get a 422 and useless "Internal server error". It's far simpler imho to map over some Results and then pack the error(s) into a more useful response. Also testing is just a lot simpler. https://pypi.org/project/result/ https://pypi.org/project/result/
- tptacek 5y agoYou just generated a 502, and spent a bunch of extra lines doing it. The 502 is bad, and if that's all I need to do, I get that almost for free from net/http's panic handler. It sounds like you don't actually have a problem here.
- claudiawerner 5y ago
- andrewmcwatters 5y agoWhat solution? There is no solution. The web just works that way. You receive some bytes and you do stuff with them. Any other expectation is a farce. Is a property missing after serialization? Can you even serialize it? Maybe a different status code returns a different mime type! OK, whatever. That’s not always an error, nor is it remotely “exceptional.”
- tptacek 5y agoI mean, I agree. That's why I'm sort of confused about what the problem is here. Yes, you can get unreliable inputs. Most apps barf on them, even if they think they don't. The barfing mechanism is pretty much the same everywhere.
- tptacek 5y agoI'm not sure what you're after, then. You have basically the same safety problems in Ruby and Python dealing with nested JSON; the thing you seem to be bothered by is that Go makes it possible to get extra safety here.
- andrewmcwatters 5y agoI’m not after anything. Why do I need “safety” from a web response? You should be liberal with what you’re accepting from a service. What “type safety” could you possibly hope for from a system you don’t control?
- akerl_ 5y ago> Why do I need “safety” from a web response? I’m not even sure where to start from that. Responses provided to an HTTP request are one of the most obvious places where enforcing structure and type safety is clearly a win.
- ibraheemdev 5y agoGo's nested struct syntax actually makes doing so quite nicer than Rust :)