4 ms·
That's a solution looking for a problem in JS. You're thinking in types instead of in terms of a dynamic language. You basically HAVE to do this in Java otherw
by hajile 8y ago
That's a solution looking for a problem in JS. You're thinking in types instead of in terms of a dynamic language.
You basically HAVE to do this in Java otherwise your program won't work. In JS, you can look everything over at runtime and dispatch from there (made much easier because first-class functions and closures are a thing).
- stickfigure 8y agoyou can look everything over at runtime Correct, that's what you have to do in dynamic languages - look at what came in from the database and manually validate+convert it into the format you actually want. Also with pretty much every other form of input (JSON bodies, form posts, queue messages, etc). It's a lot of tedium. When working with node/python/ruby, I often find myself wishing I could just declare a type and be assured that "the system" will get it right instead of me having to code it out myself. You know, like Java. Well-written Java programs are generally more concise and less verbose than well-written JS/Python/Ruby programs. Which is to say, when programmers actually validate input instead of (ahem node) crashing the process and dropping all inflight connections when someone submits a json body missing an expected field. BTW absolutely nothing prevents you from building Java apps by declaring everything as Map<String, Object>. Nobody does that because it's a horrible way to program.
- joshuamorton 8y ago> Well-written Java programs are generally more concise and less verbose than well-written JS/Python/Ruby programs. This isn't at all true. I can say this from experience using statically typed Python extensively, in an average code base, 80% of your functions, if not more, are already statically correct in Python, one just need add an annotation. Then you're just as "well written" as the Java. With or without the annotations, the code is still just as "correct". > BTW absolutely nothing prevents you from building Java apps by declaring everything as Map<String, Object>. Nobody does that because it's a horrible way to program Yes, but only because you'd need to explicitly cast things everywhere and write out declarations everywhere. If you could always elide casts and type defs, it becomes a lot less horrible. > Correct, that's what you have to do in dynamic languages - look at what came in from the database and manually validate+convert it into the format you actually want. You still have to do this in static languages. Maybe a library does it for you, and it gives your an error or something you know is a DbRecordFieldStream or whatever, but dynamic languages can do the same thing. Orms validate input in dynamic languages too. Rails and Django can validate request formats. Protobufs work in every language.
- stickfigure 8y ago> This isn't at all true. Well I guess we'll just have to disagree there. I spend a lot of time writing code in all of these languages. By the time you've bulletproofed your dynamic code, you've got more code than if you'd just declared a simple static Java type. I can define this... @Data public class Thing { final String text; final Instant when; } @Path("/thing") public class ThingResource { @POST public void doSomething(final Thing thing) { // ...blah } } ...and stop worrying in my implementation about what was actually passed in, or how a JSON string date got turned into a real date representation. This is mostly-vanilla Java. Sure you can, with enough extra code and clever libraries, hack together a crude typing system into dynamic languages to automate much of the conversion. At the end of the day you're still declaring types, and it doesn't end up being as elegant as having the type system built into the language.
- joshuamorton 8y ago> This is vanilla Java. No, its Java EE, which like I said, has an entire library devoted to safe marshalling[1]. Marshmallow does the same thing for you in python. Java EE including a marshalling library has nothing to do with static typing. This is python + flask + marshmallow (2 very common web libraries)+ a 2 line helper function: @dataclass class Thing(): text: str when: datetime.datetime @app.route('/thing', methods=['POST']) def handle(): thing = unmarshall(Thing, request.form) # blah Or, like I said, use protos, where this would be something like from thingproto import Thing, ThingService, ThingResponse class ThingServiceHandler(ThingService): def HandleThing(request: Thing, response: ThingResponse): # blah and everything is validated. [1]: https://dennis-xlc.gitbooks.io/restful-java-with-jax-rs-2-0-en/en/part1/chapter6/custom_marshalling.html https://dennis-xlc.gitbooks.io/restful-java-with-jax-rs-2-0-...
- stickfigure 8y agoI'm not quite sure what you're getting at with the "No, it's Java EE" comment. JAX-RS is a Java standard, with several implementations, and you don't need a "Java EE Server" or anything magical like that to use it. And that link to the Custom Marshalling section of the JAX-RS docs is a little weird; my example doesn't require monkeying with low-level stuff like that and most users don't. Dragging protobufs into this is weird too; you've ignored the IDL and build infrastructure required to set that up, and in any case that's specific to when you're working with protobuf APIs. I'll go back to my earlier point, which I think you've illustrated fairly well, which is that well-written Java code tends to be more concise and less verbose than Python (and friends). Our two examples are nearly identical in terms of meaningful lines of code, but in the Python example you have to ask for marshaling. I'll also point out that flask (which I use myself for python webapps) handlers are forced to interact with flask-specific objects and therefore are obnoxious to test; the JAX-RS example is pure program logic and can be tested as vanilla Java code. This is one of the big advantages of moving marshaling "out" of your program code.
- tracker1 8y agoWhy do I need to manually convert anything? Even then... var results = (await sql.query` ... `).recordsets[0].map(rowToObject); It's really easy... no need for complicated ORM/ODM tooling at all. As far as the size... create a docker container from node:10-alpine to run a given node application, and create a similar container with any application running full Java. And compare the final size.
- stickfigure 8y agoDid a date column get mapped to Date, moment, date-fns, luxon, or any of the dozen other choices that your shop might standardize on? I've never heard anyone server-side care about the size of a deployable. It's the size of the codebase that's an issue. Tedious conversion code does not work in javascript's favor.