Transcript
This transcript was autogenerated. To make changes, submit a PR.
Hello, and welcome to our session on Turbocharged Coline.
The agenda for the session is as followed.
We will start with an introduction of who we are, what we do, and what
inspired us to deliver this talk.
In the conference today, we will take a brief look at the history of the
web and the current state of affairs.
We will have a look at the hot wire toolkit, the problem it tries to
address, and especially at Turbo.
Which will be followed by a demo.
So who are we?
Hi.
Hi.
I am TSA and my co-presenter, Chiam, or as he's nicknamed, are both
senior technologists at Infosys.
We have worked on various domains like identity and access management,
platform engineering, and a tech.
We are also the co-leader of the Go Guild.
A few words on the gu.
Go First is a Go Line user group.
At Infosys, we act as consultants to the wider organization
on everything related to go.
The idea behind forming this group was to provide the go developers in
the organization with a forum where they can share their learnings, come
with their challenges, and also work on some cool project ideas that can
later be used as accelerators in one or more of our many client projects.
Accelerators give us freedom, as in there are no prescribed
requirements to start with.
We can innovate and improvise as we go.
They give us the opportunity to explore and experiment
with new tools and techniques.
But on the flip side, we need to work with the limited bandwidth of our fellow
developers who take time out of the busy schedule to participate in this endeavor.
Does, we need to set realistic milestones to make sure we make
progress within the constraint.
After having a roadmap in place, it becomes imperative to carefully
pick and choose the tools we use to build the application.
Not only should the tool set help us reach our goal, but also compliment
the strengths and interests of the developers working on the project.
And hey, side projects should be fun, right?
This is a typical modern tech stack with each layer designated to handle specific
functionalities like user interface, business logic, and data management.
Picking the best options from each layer can be a difficult task.
With options offering similar features, it becomes even harder.
We were sorted on the server side technologies.
We knew what we wanted to use, our favorite language,
go for building the backend.
We repurposed a Postgres instance that was used for A POC earlier.
We also found a VM to host our application on while we were deliberating on which
framework to use for our front end.
There was a moment where we asked ourselves, do we even need one of
these frameworks to build a front end?
Can't we just stick to plain old STML and CSS, but at the same time,
we wanted to be sure we do not end up building a product that looks
and feels like something from a gon.
At this point, I would like us to look back at the history
and evolution of the web.
In the nineties, we had technologies like CGI, script, PHP, and H, TM L. Times
were simpler, the backend application would render the UI and send it to the
browser to be displayed on the screen.
the 2000 saw the rise of web APAs thanks to Ajax, a technique
that allowed for the asynchronous application of the page without
refreshing the screen in the 2000 tens.
With more and more people making use of the internet, service providers
started finding it increasingly difficult to scale their offerings
to cater to the rising demand.
This decade saw many notable advancements in software technology
to deliver services at scale.
SPS, or single page applications came about during that time to address the
challenges of scale at a few other evolving needs, and by the end of the
decade, it led to its proliferation with multiple such libraries and frameworks
offering similar functionality.
Forward to today.
Most of the services and application we u we use on a day-to-day
basis, are powered by sps.
Sadly, developers treat sps and, as the default option or sometimes
the only option for building front end, irrespective of whether our
solution would really benefit from what s ps have to offer.
And despite the technical requirements and complexities, SPS bring along with them.
In our quest to find a simpler approach in building front ends for
the 2020s, we stumbled upon the Roca.
It turns out a group of developers had faced the same dilemma as us.
Their collaborative efforts and shared experiences resulted in a recommendations,
in a set of recommendations based on well established concepts like
rest and progressive enhancement.
Roca or the resource oriented Client Architecture style guide
is a set of recommendations for building web application front end.
The recommendations are based on a few well-established ideas like unru,
JavaScript, progressive Enhancement.
Those are related strategies for building front ends that offer the core features
to all its users while providing enhanced experience to users with modern browsers.
The guide also recommends building server side applications that
return semantic HS TML, that is independent of the layout information.
Enter Hotwire or HTML over the wire is a toolkit that aligns with the
recommendations made in the style guide like the usage of semantic
STML, and unobtrusive JavaScript.
The toolkit is part of the Rails ecosystem and is running in production
for apps like Basecamp and hey.com.
Hotwire consists of three libraries Turbo that lets you decompose your
page into independent segments that can be updated independently.
Stimulus is a lightweight JavaScript, a lightweight JavaScript framework that
gives you the means to attach JavaScript to STML, to S TM L elements using simple
annotations and native that lets you run your, your hot buyer application
natively on Android and iOS based devices.
This is your typical flow with ps. You have an application written in
JavaScript that runs on the browser.
It interacts with the backend server by making asynchronous
calls and on receiving a response.
It processes the data and then proceeds to update the page without deloading, the
complete page Turbo offers you similar capabilities without you having to write
even a single line of JavaScript code.
Turbo lets you decompose your webpage into independent units called Frames, which
enables the underlying library to uniquely identify and update these elements when
a page navigation occurs, or when a form, or when a form submission, event
occurs, In situations where you don't want to replace an entire section with
something new, but you would rather upend or prepend a new element to it, you have
the option of making use of turbo streams.
It gives you nine different options for manipulating elements in the do
Turbo streams also has support for web sockets and service id.
So in situations where you want your server to push updates to your front
end, you get it out of the box.
Okay?
Now it's time for a short demo.
Okay.
So this is a simple application that has a form and when you,
when you type in your name.
And submit the form.
You are shown a greetings message here.
So if you look at the.
This is the main go, the main go file where we have the, the
app, the application running.
So if you look at the backend code here, we've got two handlers.
the index handler and the greet handler.
The index handler is used to serve the main, the index page, which has the.
Which has the form and then the greetings handler.
it is a post endpoint, which basically accepts the form value.
and it displays, it executes the go, the greetings view, and it
displays the, the greetings message.
So also note that we have added a synthetic delay of a hundred
milliseconds to, to simulate the applications in the real world.
so if you look at the templates here.
So we can see we've got two templates.
We've got Index and Greetings.
So the index template, here consists of the form and a heading.
The Greetings.
It has the same heading and also the paragraph tab, which
contains the, Greetings message.
We have also extracted, the, the header and the photo of our application
in, into individual, templates.
we are calling it header and photo, and we've put them inside the
layouts, the layout subdirectory.
So the header contains the head tag, the starting the opening
STML tag and the opening body tag.
Whereas the footer template contains the, the closing, the
closing body N-S-T-M-L tags.
Now this application does not make use of, of any of the hot wired constructs.
So if we submit this form again, and if we look at the network tab, so you'll
notice that the server response with the, the, with the new webpage and
the browser has to reload the webpage, to display the greetings message.
Now what if we want to, make sure that not the we only get, we can display
the, just the greetings message without having to reload the entire application.
So now let's quickly jump to the other branch where we have included or where
we have implemented, turbo Frame.
Cool.
So here first we need to include, the turbo distributable, in our application.
So here we come to the header, layout, and we include, the
distributable in a script type.
then we need to modify the, the, the template.
So here, if we look at the index template, so just about the form
type, we, we have added a turbo frame type with the idea of message.
and, notice we have removed the greetings, template or the greetings
view, and we have moved it into partial.
So now this, instead of, returning the, returning a new page.
What this will, do is it, this essentially becomes our API or rather the response
of our API of the greetings API.
So when the greetings API is gets invoke, it renders this view or this partial,
and it returns this as a response.
So here we've got a, we've got a turbo frame, element
with the, with the ID message.
And here if you look at the, if you go back, to our index template.
So what we can notice is, we have this turbo frames, tag right
above the form which will get.
Replaced.
once the, once this browser receives the response from the backend.
And here also we have, we have provided an attribute, data turbo frame, which,
tells, turbo, which particular turbo frame to update when it receives the response.
So now if we run this application.
Let's go to the index page.
Cool.
And if we enter a name
and submit it, then we can see that, this is, this becomes,
this changes to an XHR request.
over here.
So we can see it's a fetch request.
And the server responds with this, with this turbo frame, which then
is updated by, which then hot buyer or turbo uses to update the dome.
But what if we don't want to, replace the entire element?
What if you want to upend.
the response to one of the existing elements.
So say for example, a chat application, right?
Where when you, when you are chatting, when the user is, interacting with
the web application, you would want to, ideally what you would want
to do is you would want to append the messages as in when they come.
So let's take a look at a chat application, a sample chat
application that we have built.
So this is a sample chat application where the user can come and, enter a message.
So I can ask a question like, can you tell me about the Con 42 con current?
Now, this particular version does not make use of any of the turbo features.
So if you look at the network tab now.
If we, yeah, so if we send this message,
we can see that the, that the backend responds with a new page, which is then
rendered by the, browser, on the screen.
If we take a look at the code.
So here, if we, if you look at the, if you look at the backend code,
we've got, we've got one addition in terms of the, in terms of services.
So we've got, we've got a Germany service, which is basically a thin wrapper over an
s TT P client, which helps us communicate with Germany and get the chat completions.
And, if we look at the templates, so for this application
we have a single template.
So this is the index or the index template.
So here, we have the form, which lets you type in the message and send it.
And on top of that, we are, we are rendering the messages that we receive
from either the user or from the bot.
So that is done by, storing the message.
in, in memory.
So we have a message struck and we've got a sender and a text.
So this can be, the sender can either be human or a bot.
And the text, responds to the corresponding message.
And we have a struck called, messages.
which, which includes an area of, of messages.
And, so whenever, as and when we receive messages, so whenever we receive a new
request, we add that message, into the ra.
And then when we get the corresponding res, response from the, from the
Gemini model, we'll add the message, marking it as bot or as a bot message.
So this is what the application looks like.
It's a pretty simple application, so every time you send a message,
the request goes to the backend.
It basically, gets the response from the, from, from Gemini, then renders the, then
renders the view along with the message history and sends it back to the user.
Now if you want to make this process asynchronous, and if you want to
make that partial update, then let's check out, check out Turbo Stream.
Good.
So here, if we look at the index, so the routes don't change.
we still have, two routes.
So one is the index handler, and, which basically serves the index.
Do, which, serves the index view.
And then we have a chat handler, which basically accepts the OR, or takes the
request, extracts the extracts, the message gets the completion from Gemini
and it, it sends back the message segment.
Partial.
So here, what the, the change that we can see here is instead of a template
which gets s rendered here we have a diff tag with the ID messages,
which provides, a target, which can be used as a target identifier by
turbo to make the partial updates.
Now if we look at the partials, so we have created a new
partial call, message segment.
So as you can see, we, the API, the chat, API now basically returns a turbo stream
element, with a few instructions for, with a few instructions, for turbo for this.
So we've got an, we've got an append, We got an action attribute which
says what to do with the response.
So here it clearly mentions that we want to append.
The, the response to the target.
And here we need to pass the target identifier.
So we pass messages as the identifier.
turbo looks for, for an element in the dome with the ID target and
it upends the, the response to it.
So another thing to note here is that, the, your response need to, needs to
be nested inside the template tags.
For this entire mechanism to work.
And the final change that we need is, if we go back to main.
So now if you notice over here we were sending the content type, we were setting
the content type to text HTML for the, in the previous cases where we were just
sending back, the entire H Tm L page, even for, even for Turbo, even for turbo
frame, it works if you send the response.
if your response contains a header, which signifies the
content type is a text, HTML.
But in case of, turbo Stream, we need to, set it to text
vendor, turbo Stream, or html.
Otherwise, it does not work for some reason.
Okay, so now let's run this application.
Cool.
We go to local host A 80 right now, we can ask the same question
to notice that the request changed to, to a fetch tape.
And the response that we receive from it.
Okay, so the response here, it looks like this and we can
continue chatting with this, right?
So say, when was the first conference?
That was the first, conference.
Okay, so we have the answer here.
And if you look at the response that we received, it's just,
it's just the last message.
So now it's not sending the entire STML page, it's just sending the
response to the previous request.
okay.
So we can continue this conversation, is.
Go, functional book and language.
So as you can see, the backend only responds with only the only response,
with only the code segment that it wants.
Turbo a pen to the messages Dave.
Make sure you check out our repository, Gocha Turbo, where we have implemented a
chatbot application using our web sockets and integrated it with turbo streams.
So how has the journey been for us so far?
We have embraced some of the recommendations made in Roca style Guide
to keep our tech stack lean yet effective.
As a result, we have a single repository and a single pipeline
for the entire application.
We also notice 50% reduction in effort compared to our
original estimates with SPA.
And finally, we have a happy bunch of developers who can
work with a simple set of tools.
We encourage you to visit the website of Roca style Guide and have a look
at the recommendations, and also give Hotwire a try for your next site project.
Thank you for joining us today.
Until next time.
Goodbye.