Serverless Application with Flutter & Lambda

Few days ago, Google has announced the beta release of Flutter at Mobile World Congress 2018. A mobile UI framework to build native apps for both iOS and Android. It uses Dart to write application. The code is compiled using the standard Android and iOS toolchains for the specifc mobile platform, hence, better performance and startup times.

Flutter has a lot of benefits such as:

  • Open Source.
  • Hot reload for quicker development cycle.
  • Native ARM code runtime.
  • Rich widget set & growing community of plugins backed by Google.
  • Excellent editor integretation: Android Studio & Visual Studio Code.
  • Single codebase for iOS and Android, full native performance (does not use JavaScript as a bridge or WebViews) .
  • React Native competitor.
  • Dart feels more Java, easy for Java developers to jump on it.
  • It use Widgets, so for people coming from web developement background everything should seem very familiar.
  • It might end the Google vs Oracle Java wars.

So it was a great opportunity to get my hands dirty and create a Flutter application based on Serverless Golang API I built in my previous post “Serverless Golang API with AWS Lambda



The Flutter application will call API Gateway which will invoke a Lambda Function that will use TMDB API to get a list of movies airing this week in theatres in real-time. The application will consume the JSON response and display results in a ListView.

Note: All code can be found on my GitHub.

To get started, follow my previous tutorial on how to create a Serverless API, once deployed, copy to clipboard the API Gateway Invoke URL.

Next, get the Flutter SDK by cloning the following GitHub repository:

1
git clone -b beta https://github.com/flutter/flutter.git

Note: Make sure to add flutter/bin folder to your PATH environment variable.

Next, install the missing dependencies and SDK files:



Start Android Studio, and install Flutter plugin from File>Settings>Plugins :



Create a new Flutter project:



Note: Flutter comes with a CLI that you can use to create a new project “flutter create PROJECT_NAME

Android Studio will generate the files for a basic Flutter sample app, we will work in lib/main.dart file:



Run the app. You should see the following screen:



Create a simple POJO class Movie with a set of attributes and getters:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Movie {
String poster;
String title;
String overview;
String releaseDate;

Movie({this.poster, this.title, this.overview, this.releaseDate});

getTitle(){
return this.title;
}

getPoster(){
return this.poster;
}

getOverview(){
return this.overview;
}

getReleaseDate(){
return this.releaseDate;
}
}

Create a widget, TopMovies, which creates it’s State, TopMoviesState. The state class will maintain a list of movies.

Add the stateful TopMovies widget to main.dart:

1
2
3
4
class TopMovies extends StatefulWidget {
@override
createState() => new TopMoviesState();
}

Add the TopMoviesState class. Most of the app’s logic will resides in this class.

1
2
3
4
class TopMoviesState extends State<TopMovies> {
List<Movie> _movies = new List();
final _apiGatewayURL = "https://gfioehu47k.execute-api.us-west-1.amazonaws.com/staging/main";
}

Let’s initialize our _movies variable with a list of movies by invoking API Gateway, we will iterate through the JSON response, and add the movies using the _addMovie function:

1
2
3
4
5
6
7
8
9
10
@override
void initState() {
super.initState();
http.get(this._apiGatewayURL)
.then((response) => response.body)
.then(JSON.decode)
.then((movies) {
movies.forEach(_addMovie);
});
}

The _addMovie() function will simply add the movie passed as an argument to list of _movies:

1
2
3
4
5
6
7
8
void _addMovie(dynamic movie){
this._movies.add(new Movie(
title: movie["title"],
overview: movie["overview"],
poster: movie["poster_path"],
releaseDate: movie["release_date"]
));
}

Now we just need to display movies in a scrolling ListView. Flutter comes with a suit of powerful basic widgets. In the code below I used the Text, Row, Image widgets. In addition to Padding & Align components to display properly a Movie item:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Widget _fetchMovies() {
return new ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (context, i){
return new Card(
child: new Container(
height: 250.0,
child: new Padding(
padding: new EdgeInsets.all(2.0),
child: new Row(
children: <Widget>[
new Align(
child: new Hero(
child: new Image.network("https://image.tmdb.org/t/p/w500"+this._movies[i].getPoster()),
tag: this._movies[i].getTitle()
),
alignment: Alignment.center,
),
new Expanded(
child: new Stack(
children: <Widget>[
new Align(
child: new Text(
this._movies[i].getTitle(),
style: new TextStyle(fontSize: 11.0, fontWeight: FontWeight.bold),
),
alignment: Alignment.topCenter,
),
new Align(
child: new Padding(
padding: new EdgeInsets.all(4.0),
child: new Text(
this._movies[i].getOverview(),
maxLines: 8,
overflow: TextOverflow.ellipsis,
style: new TextStyle(fontSize: 12.0, fontStyle: FontStyle.italic)
)
),
alignment: Alignment.centerRight,
),
new Align(
child: new Text(
this._movies[i].getReleaseDate(),
style: new TextStyle(fontSize: 11.0, fontWeight: FontWeight.bold),
),
alignment: Alignment.bottomRight,
),
]
)
)
]
)
)
)
);
}
);
}

Finally, update the build method for MyApp to call the TopMovies widget instead:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'WatchNow',
home: new Scaffold(
appBar: new AppBar(
title: new Text('WatchNow'),
),
body: new Center(
child: new TopMovies(),
),
),
);
}
}

Restart the app. You should see a list of movies airing today in cinema !



That’s it ! we have successfully created a Serverless application in just 143 lines of code and it works like a charm on both Android and iOS.

Flutter is still in womb so of course it has some cons:

  • Steep learning curve compared to React Native which uses JavaScript.
  • Unpopular comparing to Kotlin or Java.
  • Does not support 32-bit iOS devices.
  • Due to autogenerated code, the build artifact is huge (APK for Android is almost 25 Mb, While I built the same app in Java for 3 Mb).

But for a beta release it look very stable and well designed. I can’t wait to see what you can build with it !

Drop your comments, feedback, or suggestions below — or connect with me directly on Twitter @mlabouardy.

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×