diff --git a/code-samples/community/serving/helloworld-dart/Dockerfile b/code-samples/community/serving/helloworld-dart/Dockerfile index db97e409b5f..c333dee714f 100644 --- a/code-samples/community/serving/helloworld-dart/Dockerfile +++ b/code-samples/community/serving/helloworld-dart/Dockerfile @@ -1,7 +1,21 @@ -# Use Google's official Dart image. -# https://hub.docker.com/r/google/dart-runtime/ -FROM google/dart-runtime +# Use latest stable channel SDK. +FROM dart:stable AS build -# ONBUILD instructions for COPY and pub get is defined in the google/dart-runtime image, -# allowing you to keep this file very simple, see: -# https://github.com/dart-lang/dart_docker/blob/master/runtime/Dockerfile.template#L15-L18 +# Resolve app dependencies. +WORKDIR /app +COPY pubspec.* ./ +RUN dart pub get + +# Copy app source code (except anything in .dockerignore) and AOT compile app. +COPY . . +RUN dart compile exe bin/server.dart -o bin/server + +# Build minimal serving image from AOT-compiled `/server` +# and the pre-built AOT-runtime in the `/runtime/` directory of the base image. +FROM scratch +COPY --from=build /runtime/ / +COPY --from=build /app/bin/server /app/bin/ + +# Start server. +EXPOSE 8080 +CMD ["/app/bin/server"] diff --git a/code-samples/community/serving/helloworld-dart/README.md b/code-samples/community/serving/helloworld-dart/README.md index 18744a3d4de..57c8bb619a2 100644 --- a/code-samples/community/serving/helloworld-dart/README.md +++ b/code-samples/community/serving/helloworld-dart/README.md @@ -17,67 +17,24 @@ that you can use for testing. It reads in the env variable `TARGET` and prints ## Recreating the sample code -While you can clone all of the code from this directory, it is useful to know -how to build a hello world Dart application step-by-step. This application can -be created using the following instructions. +While you can clone all of the code from this directory, we recommend you create +your hello world Dart application by using the `dart` developer tool. This takes +just a few steps: -1. Create a new directory and write `pubspec.yaml` as follows: +1. Create a new Dart app using the `server_shelf` template: - ```yaml - name: hello_world_dart - publish_to: none # let's not accidentally publish this to pub.dartlang.org - - environment: - sdk: ">=2.12.0 <3.0.0" - - dependencies: - shelf: ^1.0.0 + ```shell + > dart create -t server-shelf helloworld-dart ``` -2. If you want to run locally, install dependencies. If you only want to run in +1. If you want to run locally, install dependencies. If you only want to run in Docker or Knative, you can skip this step. - ```bash - > pub get - ``` - -3. Create a new file `bin/server.dart` and write the following code: - - ```dart - import 'dart:io'; - - import 'package:shelf/shelf.dart'; - import 'package:shelf/shelf_io.dart'; - - Future main() async { - // Find port to listen on from environment variable. - final port = int.parse(Platform.environment['PORT'] ?? '8080'); - - // Read $TARGET from environment variable. - final target = Platform.environment['TARGET'] ?? 'World'; - - Response handler(Request request) => Response.ok('Hello $target'); - - // Serve handler on given port. - final server = await serve( - const Pipeline().addMiddleware(logRequests()).addHandler(handler), - InternetAddress.anyIPv4, - port, - ); - print('Serving at http://${server.address.host}:${server.port}'); - } - ``` - -4. Create a new file named `Dockerfile`, this file defines instructions for - dockerizing your applications, for dart apps this can be done as follows: - - ```Dockerfile - # Use Google's official Dart image. - # https://hub.docker.com/r/google/dart-runtime/ - FROM google/dart-runtime + ```shell + > dart pub get ``` -5. Create a new file, `service.yaml` and copy the following service definition +1. Create a new file, `service.yaml` and copy the following service definition into the file. Make sure to replace `{username}` with your Docker Hub username. diff --git a/code-samples/community/serving/helloworld-dart/analysis_options.yaml b/code-samples/community/serving/helloworld-dart/analysis_options.yaml new file mode 100644 index 00000000000..dee8927aafe --- /dev/null +++ b/code-samples/community/serving/helloworld-dart/analysis_options.yaml @@ -0,0 +1,30 @@ +# This file configures the static analysis results for your project (errors, +# warnings, and lints). +# +# This enables the 'recommended' set of lints from `package:lints`. +# This set helps identify many issues that may lead to problems when running +# or consuming Dart code, and enforces writing Dart using a single, idiomatic +# style and format. +# +# If you want a smaller set of lints you can change this to specify +# 'package:lints/core.yaml'. These are just the most critical lints +# (the recommended set includes the core lints). +# The core lints are also what is used by pub.dev for scoring packages. + +include: package:lints/recommended.yaml + +# Uncomment the following section to specify additional rules. + +# linter: +# rules: +# - camel_case_types + +# analyzer: +# exclude: +# - path/to/excluded/files/** + +# For more information about the core and recommended set of lints, see +# https://dart.dev/go/core-lints + +# For additional information about configuring this file, see +# https://dart.dev/guides/language/analysis-options diff --git a/code-samples/community/serving/helloworld-dart/bin/server.dart b/code-samples/community/serving/helloworld-dart/bin/server.dart index a2b61c08d2e..d6d2b1b3d36 100644 --- a/code-samples/community/serving/helloworld-dart/bin/server.dart +++ b/code-samples/community/serving/helloworld-dart/bin/server.dart @@ -2,21 +2,31 @@ import 'dart:io'; import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart'; +import 'package:shelf_router/shelf_router.dart'; -Future main() async { - // Find port to listen on from environment variable. - final port = int.parse(Platform.environment['PORT'] ?? '8080'); +// Configure routes. +final _router = Router() + ..get('/', _rootHandler) + ..get('/echo/', _echoHandler); + +Response _rootHandler(Request req) { + return Response.ok('Hello, World!\n'); +} - // Read $TARGET from environment variable. - final target = Platform.environment['TARGET'] ?? 'World'; +Response _echoHandler(Request request) { + final message = request.params['message']; + return Response.ok('$message\n'); +} + +void main(List args) async { + // Use any available host or container IP (usually `0.0.0.0`). + final ip = InternetAddress.anyIPv4; - Response handler(Request request) => Response.ok('Hello $target'); + // Configure a pipeline that logs requests. + final handler = Pipeline().addMiddleware(logRequests()).addHandler(_router); - // Serve handler on given port. - final server = await serve( - const Pipeline().addMiddleware(logRequests()).addHandler(handler), - InternetAddress.anyIPv4, - port, - ); - print('Serving at http://${server.address.host}:${server.port}'); + // For running in containers, we respect the PORT environment variable. + final port = int.parse(Platform.environment['PORT'] ?? '8080'); + final server = await serve(handler, ip, port); + print('Server listening on port ${server.port}'); } diff --git a/code-samples/community/serving/helloworld-dart/pubspec.yaml b/code-samples/community/serving/helloworld-dart/pubspec.yaml index 6f8965d5f30..fd2703e13d1 100644 --- a/code-samples/community/serving/helloworld-dart/pubspec.yaml +++ b/code-samples/community/serving/helloworld-dart/pubspec.yaml @@ -2,7 +2,14 @@ name: hello_world_dart publish_to: none # let's not accidentally publish this to pub.dartlang.org environment: - sdk: '>=2.12.0 <3.0.0' + sdk: ">=2.17.0 <3.0.0" dependencies: - shelf: ^1.0.0 + args: ^2.0.0 + shelf: ^1.1.0 + shelf_router: ^1.0.0 + +dev_dependencies: + http: ^0.13.0 + lints: ^2.0.0 + test: ^1.15.0