(upbeat music)
- Hello everybody,
and welcome to full-stack with either Kotlin or Dart on Google Cloud.
My name is Grant Timmerman,
and I'm joined today by James Ward and Tony Pujals.
So let’s talk about Serverless on Google Cloud.
So what is Serverless?
Well, first, Serverless is an operational model
where you have no infrastructure management,
you have managed security, and you pay per use.
Second, it’s a programming model, is service-based.
It’s where you can build event-driven services
and it uses open-source.
But customers often ask us the following questions.
“How can we use existing binaries?
We can't be locked in.
Can you support this language?
Or how do I choose between containers and Serverless?”
So that's where Cloud Run comes in.
Cloud Run allows you to develop and deploy highly scalable containerized applications
on a fully managed serverless platform.
With Cloud Run, you run containers.
So containers allow you to run any language, any library, any binary,
where you can go and pick from an ecosystem of base images.
One of the great parts about Serverless and Cloud Run is that you pay per use.
So that means depending on your CPU, memory and requests usage,
your billed to the hundred milliseconds.
So you can go and make your services public
with the allow unauthenticated fine.
This is great for websites, for example.
But let’s say you don’t want public.
You want to make a private service.
So private is the default for Cloud Run.
So it's great for microservices
and for handling events and asynchronous tasks.
Next up, Eventarc.
Eventarc is a Google Cloud product
that allows you to deliver asynchronous events to your applications.
So let's back up. Why events?
Well, we’re in a world moving towards real-time communication.
So that means your applications are expecting rapid delivery
and consumption of different services.
many to many messages,
where you might get a message from a different service, or maybe a couple.
And then you’re also expecting on-demand scalability and costs.
So let's say in real life, like you get a new photo
is that added to your Cloud storage bucket?
Maybe you get a new message from Pub/Sub or a new audit log.
Well, with Eventarc, you can take all of these sources
and you can create a trigger.
This is the main resource in the vendor.
This allows you to specify which service will receive that event.
And so whenever one of those events is fired,
it’ll create an event that’s sent to your Cloud Run service.
So what is a CloudEvent?
Well, it uses the HTTP protocol.
So within your HTTP request is a CloudEvent
which has metadata, some contexts,
these area stand your attributes like ID, the time it is sent,
and then it has your actual application data
With Eventarc, we use binary encoded CloudEvents.
So this means you’ll get an HTTP post request to your slash route.
You’ll get some standard HTTP headers
that are for CloudEvents, with the CE- flag,
and then you’ll get your normal payload,
in this case for a Pub/Sib event.
We also have a set of libraries
that allows you to write your applications as a function.
These are available in a large set of languages,
including Kotlin and Dart,
and can listen to HTTP requests and CloudEvents.
So we know that full stack developers like to
use the same language for the front-end and back-end.
One of the awesome things that’s available with Kotlin and Dart
is that we can use the same language across both the front-end and back-end.
So now James and Tony can go and show you the magic.
- Hi, I’m James Ward.
So I want to show you Kotlin, multi-platform
running on Google Cloud, and a bunch of clients.
So first I'll show you the demo.
I’m in a web application here that’s running on Google Cloud
using a Google Cloud load balancer and Cloud Run and Cloud SQL.
And this is just a basic data-driven application.
So I can come in here and add a bar to my database.
So that's the web application. Now, we also have a desktop application
that works the same way with a different UI.
I can of course add bars in there. And then I also have Android application
which works the same way,
and I can come in and add bars on the Android application.
But then for yet another client, let’s hop into my IDE,
and I have a CLI application.
So I can run that. This will compile.
I could of course turn this into actually a native application
and distribute it to Mac, Linux and Windows,
but here I’m just running it from my IDE just to see how that works.
And then we can, of course, come in
and add a new bar and see the bars over there.
So all those different clients were connecting up to my server,
running on Cloud Run.
And of course, they’re all built with Kotlin. So let's walk through the code.
I have a shared common module in this data KT file,
and this allows me to share code
across all the different clients and servers that are part of this application.
In this case, all that this common module has
is a data class, which is a bar.
So this holds my data that I store into the database.
It has a primary key that’s a long and it has a name that's a string.
So that's the common module.
Now let's dive into the server.
My server is built with Spring Boot
and it uses Spring Native to compile this down
into a native application that runs on Cloud Run.
Of course, we can containerize that application
into a docker container and it starts up in milliseconds.
So this connects up to my database using a reactive CrudRepository,
and then, I have my rest mappings.
I have @GetMapping for api/bars
and that just does a query to the database to get my list of bars.
You’ll see that it’s a suspend fund, so that’s a non-blocking reactive request.
And then I have my PostMapping, allowing me to add new bars to my database
that just takes a JSON post and parses the JSON,
and then allows me to save that bar. So that’s shared from that common module,
I save that into the database and then do an HTTP response.
That’s all there is for my Spring Boot server.
Let's take a look at the web application. Again my web application is written in Kotlin
and I get to take advantage of all the nice features of Kotlin.
It’s all type safe, but I can do DOM manipulation in the browser,
and do like the Window Fetch API to go fetch my bars.
Of course, that comes back as an array of bar.
So again, we’re using that code between,
this compiles down into JavaScript.
So I get to reuse that and reuse the Kotlin code,
write my code in Kotlin,
and there’s the rest of my UI that’s manipulating the UI,
creating the form, adding the event handlers, that sort of thing.
So that's my web application.
To look at the Android and desktop applications,
I actually have a shared module for the UI,
because something called Jetpack Compose allows me to share code
between the desktop application and the Android application.
In this case,
I have a bars which takes the URL to connect to.
I’m using a Ktor client library to make my HTTP requests.
And then I have my UI written in Jetpack Compose.
So fetching the list of bar again, you’ll see the code reused between those.
And then I have my UI that’s rendering the list of bars
and has the form with the form handler and that sort of thing, to add a bar.
Then the Kotlin code,
all it has to do is set the content to that reusable composed piece there.
And then similarly, my desktop application creates a window
and then reuses that bar UI from that Kotlin module.
So that’s all of the code that it took to build this application with the server,
the web application, the Android application, the desktop application,
and then the CLI, which is over here, is similar to what you saw with the Spring Boot
client because I’m using Spring Boot to create the command line client as well.
And then with Spring Native I can compile this down into a native executable
if I wanted to distribute that to the different platforms.
That’s all the code there is for the application.
You can find that all up on my GitHub, github.com/jamesward,
and Kotlin-bars, and instructions for how to deploy that up
on Google Cloud are all in that repository. So check that out.
That’s Kotlin and we’re using that across many different platforms.
So hopefully that was useful for you. Now, over to Tony.
- Hey everybody, I’m Tony Pujals, I’m an engineer at Google.
And today we're going to talk about full-stack Dart on Google Cloud.
I'm a firm believer that you should use whatever language is the most appropriate
to solve the problems you need to solve on the back-end.
So if you’re, for example,
writing a service that has to do a lot of numerical calculations,
then maybe you should be using Python or R.
That considered, for most development teams you’ll find that there’s a lot of synergy,
a lot of momentum that you get when you use the same language
on the front-end and on the back-end. And what we’re finding
is that Flutter has become this really popular UI framework,
and developers are using it to build really cool cross-platform applications.
And by cross-platform,
I mean it runs on mobile, it runs on web, and it runs on desktop,
on Windows, on Mac and Linux.
And the language for programming Flutter is Dart.
I myself am new to Flutter and I am really impressed
with how cool it is for developing applications.
And I built a little demo app over the weekend.
What I’m going to demonstrate here is this little front-end app is going to talk
to our back-end app written in Dart.
Many people don’t realize you can use Dart on the back-end and it works very well.
Dart is very performant.
We compile it to a native binary application and it runs on the Cloud Run platform
in a container and starts up fast, executes fast.
So the first thing I wanna do is, I'm gonna introduce this demo.
It's here on GitHub.
You can go to subfuzion/dart-flutter-fullstack-demo.
And I’m going to do a quick workthrough.
First thing we’ll do is we’ll go into the clone of the repo on my system.
I've cloned it here under projects,
and I’ve opened up two terminal panes
to show the back-end and the front-end.
The back-end is easy to start.
You can look in the docs
and see all the commands that you would need to get going.
It’s just gonna be a build and then a run,
but I've simplified that even further.
So if you have make on your system, just run makerun
and that’s gonna start up our Dart server on local host.
And now I'm gonna go ahead and I'm going to run our front-end.
I’m on a Mac, so I’m going to target MacOS
and this is going to go ahead
and launch the application on MacOS.
Here we go. Here’s the app, it’s up and running.
I’ll enter my name, hit enter and there you go.
We can see that I got a response here.
“Bonjour Tony.” It’s in French,
and the server went ahead and logged that. There was a greeting response and success
and HTTP 200.
So here’s what’s cool. This is easy.
This is running locally, but let’s go ahead
and run this up on Cloud Run.
Let’s go ahead and submit our code.
I’ll use gcloud.
This is a beta command because it’s gonna be...
it’s a new command that does everything
in one operation. It's really cool.
It’s going to go ahead and send the contents of this directory
to the back-end.
Cloud Build will build it and deploy it on the Cloud Run.
So gcloud beta run, deploy.
The service is called greeting,
and the source is going to be in this directory,
and we want to allow-unauthenticated
for public access.
And now, we can run our app.
This time, I need to tell it I’m gonna run it in the prod environment.
I had to do this Dart defined for the environment,
EMV variable that we have defined in the app
and it will load prod.Jason this time.
And when it starts,
we’ll be able to ping our back-end. This time, it won’t be this back-end
and we'll see nothing here.
This is gonna be our Cloud Run back-end.
Notice there was a little bit of a delay the first time.
That’s because the service actually spun up.
This is Serverless.
You can set them in instance to a one but in this case it was zero.
And so there was this split second while it started.
And now if I hit it again,
it’ll be much faster.
There you go. Hello world.
So how do we know?
Let’s take a look at a look at at our logs.
Here’s the app on the back-end,
up on Cloud Run and I am going to
check out the latest logs,
and here you go.
We can see the greeting for Tony
and then the next greeting for World in our Cloud Run logs.
So let me show you what’s here in the repo.
First of all, there’s the back-end,
and we scaffold this using the DartFn tool
that’s part of the functions framework for Dart.
It's a very simple app. It's going to take a greeting request.
It responds with a greeting response.
It defaults to World if you don’t supply a name.
There’s the response.
This is what we logged.
That’s what I showed you a second ago in Cloud Run.
That's it.
The only other thing to know about this demo
is the greeting request and greeting response types.
They’re defined here in API_types.dart,
They’re JSON serializables.
So when we build the app,
the parts app also gets built for handling this utilization.
We defined it using these annotations here and that’s it.
Now on the front-end,
we have a service here for invoking this API,
it also is going to access serializers
for the greeting request and greeting response.
So when we send our request,
we encoded the name that was provided in the form.
And then we wait for the response.
We posted this request. We make sure that we set application JSON,
we get a response, and then we’re going to display it.
There’s a model for the class in here that handles sending that greeting,
and then notifying listeners.
What we are seeing is here inside of the greeting widget.
This is where the name is provided,
and this is where information gets applied in the snack bar
that shows a response that came back.
That’s it.
then just take a look at the command line version.
It’s dead simple.
Okay, so now that we’ve seen that working, let's go back here.
Again, this demo app was located here at subfuzion/dart-flutter-fullstack-demo.
All the instructions are here. It’s also a part of
one of the official examples in the functions framework for Dart,
and the functions framework for Dart is where that DartFn tool came from.
And you can come here. You can see other examples
and you can check out docs for how to get your back-end up and running.
Obviously, you know, it takes a team to get stuff done.
I wanna give thanks to some of my colleagues as well as members of the community.
So Kevin Moore, product manager at Google for the Dart team,
and Grant Timmerman, the architect for the functions framework,
Jeff Huleatt, and then,
these people in the community, Jason Rai, Jermaine Oppong and Simon Lightfoot
who all contributed in some way to the demo.
Thank you everybody, and good luck.
Good luck folks with checking out the Dart functions framework,
building your full-stack applications run on Google Cloud.
If you are curious about any of the parts that I skipped here due to time,
go ahead and take a look at this raw unfiltered unedited video
that is exactly 13 minutes long.
That shows you start to finish cloning the repo,
creating your project, all the things, all the little extra details you’ll miss
in this very short five-minute version of the video.
Thanks folks, have a great day. Bye.
(upbeat music)