How to Build a Web App with and Without Rails Libraries
shopify.engineering
shopify.engineering
I'm a Professor, I teach web development (to BSc and MSc students), and I always go through the "socket experience" before using any framework at all (usually Django, sometimes Flask). This lab exercise and another one for webservices (basically routing and sending json responses through the socket) are quite elucidative for them regarding web apps.
In the end, the message they get is that the internet is all text going back and forth (plus or minus some details).
$ telnet google.com 80
Trying 142.250.70.238...
Connected to google.com.
Escape character is '^]'.
GET / HTTP/1.1
HTTP/1.1 200 OK
Then adding a couple of headers - and realising that it really was just text. You can really tell the difference with young developers who've made that leap. % openssl s_client -quiet -connect google.com:443
depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
verify return:1
depth=1 C = US, O = Google Trust Services, CN = GTS CA 1O1
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = *.google.com
verify return:1
GET / HTTP/1.1
Connection: close
HTTP/1.1 200 OKGranted, not everyone of them will really understand all the nuances of what I try to teach them, but hopefully they’ll get some of it, and be better professionals than without that knowledge.
I was not suggesting to do an exercise. If the goal of your exercise is to show that the web is built off text being passed back and forth it can easily be shown by just looking at the network tab. From a web development perspective the exact details of how HTTP packets are encoded are not that important. For the same reason a deep knowledge of TCP is not really important.
I know that there are Reasons and blablabla but at an emotional level it's the end of an era, same to all these sites going React. The web used to be built on simple and easily-understandable tech, and now it just isn't.
No, HTTP is for TRANSFERRING hypertext. There is no reason that the transfer protocol needs to work in plain text (on top of TCP which isn't plain text either).
My introduction to web programming was raw PHP and it removes any illusions about this stuff being fancy.
>Just kidding.
Well, perhaps it should be? It's a pet-project level of software alright, and it's got a million issues; but I'd argue that dealing with HTTP and HTML at the lowest level is the best way to internalise the foundations of web development.
I have fond memories of implementing one in C (complete with multithreading and request queuing) at university. I found it immensely satisfying, I felt like I was Tim Berners-Lee back in 1990!
That knowledge came in handy some years later when I worked building a TLS intercepting proxy (basically mitmproxy, but not) as part of an automated testing tool. That job really validated why I studied computer science; I had all the prerequisite understanding to jump straight into the task from day 1.
At the same time NodeJs came out (:
I enjoy using Rails, but sometimes it's a pain in the ass, and usually because it tries to be too clever to reduce the amount of boiler platey code you need to write. In terms of code management, I'd much rather have explicit dependencies. Less `belongs_to :thing`, and more `belongs_to :thing, foreign_key: 'thing_id', klass: Thing`. Makes refactoring and code navigation so much easier.
Also, pre-Rails 5, the defaults for DB migrations and relations were trash.
Things auto running and importing themselves seems magical because no other mainstream language does that
Doesn't Rail's use of metaprogramming mean that often there isn't a simple static implementation of a method in the source code that you can go and find?
And while you can't find the method code itself, for example the generated code to access a has_many relationship, you can pretty easily find the meta programming that will generate it by following the class method name.
I've wrote a bit on this on my blog in the context of creating a (nano) web framework similar to Rails [1] and a (nano) http client library similar to requests [2].
I find this to help assure me that if I have to go one layer deep in abstraction I'd still be able to learn how it works.
[1] https://mhasbini.com/blog/lets-build-a-web-framework.html
[2] https://mhasbini.com/blog/lets-build-an-http-client.html
Interesting Shopify is sponsoring both TrufflyRuby and YJIT on MRI.
The two represent the common dichotomy between a reimplementation that potentially reach much higher performance, but will continuously have to battle for compatibility, and an in-tree development that will be limited by backward compatibility etc, but that if merged would be guaranteed to stay up to date.
Maxime explains this well in her YJIT talk [0], and it's the same with other languages such as Python, where PyPy is in most cases much faster, but tend to lag a version or two behind.
I honestly am baffled as to why anyone would not choose rails for most web apps, let alone basic CRUD apps. Maybe Django would be an alright substitute, I just dislike Python as a language/ecosystem. And the Rails core and gem ecosystem is just so mature at this point, any new feature you need is just a gem install away (hyperbole a bit).
In the end, it's not a huge deal which stack you go with and great, successful companies have been built on all of these and even weirder stacks. Just wish the world settled on one so we could double down on the tooling around it :)
Also recognize starting a project with what language/tools you know best is often more important than picking the most optimal one for the job.
Maybe it's the insane memory requirements of Rails leading ot large AWS bills. It can be worse than running a JVM for a fraction of the performance. Rails didn't go out of fashion for nothing.
The difference is.. Oh my!
Rails makes developing so much easier and faster. Maybe I'm dumb, but I'm so much more comfortable with batteries included and developing products the idiomatic way.
With Node, I felt like I was reinventing the wheel for every feature I wanted to add.
I just looked at the page for Express, and the sticking point is in the title: "unopinionated." I WANT a HEAVILY opinionated stack. I LOVE that I can write 1 line of code in 3 specific places in the Rails directory tree to accomplish something that would take me literally 300 lines of raw Java and Typescript in an Angular world. Some people hate it; that's their prerogative. But this is the difference between Rails and so many other stacks: opinionation.
Yes, it takes time to learn where to put stuff. If that irks you, I'd recommend staying away from Rails. The opinionation is what allows me to leverage the stack to be as productive as whole teams of people banging away on Java.
I agree rails is better in every other aspect.
I just finished a class I call GTKManySocketManager which abstracts away over the “polling” functions (poll/select/epoll).
I wish I knew it was this easy when I learned Javascript.
I hate hunting a library to do something for me—and, when I do find code I want to use, it is almost always best to modify it.
Love it. Long live the socket. Build your own stack because it’s worth it’s worth it.
loop do
client = server.accept
An infinite loop to listen for incoming requests? Is that really the right way to do this? Wouldn't this cripple your server eventually?