shorebird 0.0.1-dev.1 copy "shorebird: ^0.0.1-dev.1" to clipboard
shorebird: ^0.0.1-dev.1 copied to clipboard

discontinued
outdated

Dart serverless

Pub package Discord

Shorebird #

This package is a work in progress. If you're interested in using Shorebird, please join us on Discord: https://discord.gg/9hKJcWGcaB

Installation #

dart pub global activate shorebird
shorebird generate
shorebird run

Usage #

Shorebird uses @Endpoint, @Storable and @Transportable annotations to mark sections of your code you intend to run on the server, store in a datastore, transport over the network, etc.

@Endpoint #

@Endpoint annotations are used to mark functions that should be exposed as serverless functions. The function must return a Future<T> or Stream<T>. shorebird generate will generate the necessary server and client code to connect to the function.

import 'package:shorebird/shorebird.dart';

@Endpoint
Future<String> hello(RequestContext context) async {
  return 'Hello, world!';
}

import 'gen/client.dart'; // Generated by `shorebird generate`.

void main() async {
  var client = Client();
  var result = await client.hello();
  print(result); // Prints 'Hello, world!'
}

@Endpoint annotations can only be used on top level functions. This is part of the idea that Shorebird is a serverless architecture, your functions may end up run on differnet instances at different times and should not expect to keep state long term. To keep state, use the DataStore or (soon) Session objects.

@Storable and @Transportable #

@Storable annotations are used to mark classes that can be stored in a datastore. @Transportable annotations are used to mark classes that can be sent across the network. It's often the case that a class is both Storable and Transportable. (Currently they're treated interchangably.)

import 'package:shorebird/annotations.dart';

@Endpoint
Future<void> addPerson(RequestContext context, Person newPerson) async {
  DataStore.of(context).collection<Person>().add(newPerson);
}

@Endpoint
Future<Person> getPerson(String name) async {
  return DataStore.of(context).collection<Person>().firstWhere((p) => p.name == name);
}

@Storable()
@Transportable()
class Person {
  String name;
  int age;
}

void main() {
  var client = Client();
  var person = Person()..name = 'Bob'..age = 42;
  await client.addPerson(person);
  var bob = await client.getPerson('Bob');
  print(bob.age); // Prints '42'
}

Known issues #

  • shorebird run does not (yet) call shorebird generate before running. This means that if you change Endpoints, Storable, or Transportable classes you need to run shorebird generate manually before running.
  • shorebird CLI dependencies are currently present in package:shorebird's pubspec.yaml. They will be moved to a separate package soon.
  • @Storable and @Transportable do not yet generate toJson/fromJson methods. Should be easy to fix, for now classes should also use json_serializable.
  • shorebird generate cannot yet handle nullable types in endpoint parameters. This is a bug in the code generator.
  • Don't yet have a nice way to handle error reporting from the server. currently Client.post will throw an exception if the server returns a non-200 response.
  • shorebird login is currently a stub.
  • shorebird deploy is not fully wired up yet.

TODO / Demo #

  • shorebird create (could be a whole app, not just counter)
  • shorebird run
  • shorebird deploy hosted version on the web, and download links Also offer a push-to-deploy separate flow.

Later #

  • shorebird shorebirdify add shorebird to an existing project.
  • Remove 'json_serializable'and 'build_runner' dependencies everywhere.