Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0 Dart client generation #3

Merged
merged 37 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
51ffd45
v0 working against test server
austinmilt Apr 11, 2024
612d9e0
remove unused docs
austinmilt Apr 11, 2024
dd49135
update pubspec docs
austinmilt Apr 11, 2024
e34b5fa
make the test script flexible wrt webrpc script location
austinmilt Apr 11, 2024
4067680
update test code generation to dart analyzed directory
austinmilt Apr 11, 2024
d6aef91
add custom schema tests and datetime conversions
austinmilt Apr 12, 2024
16e13ef
schema validation WIP
austinmilt Apr 12, 2024
d20bc1d
illustrate missing fields for User
austinmilt Apr 12, 2024
8e427cc
support null and any types in schema
austinmilt Apr 16, 2024
9bf79c0
support recursive objects and non-string map keys
austinmilt Apr 16, 2024
036b9a0
additional custom schema for API calls
austinmilt Apr 18, 2024
d2c19be
use BigInt for 64-bit ints
austinmilt Apr 18, 2024
fd4ed59
use BigInt for 64-bit integers
austinmilt Apr 18, 2024
af88a2c
ignore integer issues (no BigInt)
austinmilt Apr 18, 2024
41fde34
finish core types tests
austinmilt Apr 18, 2024
62152ba
test simple structs
austinmilt Apr 18, 2024
08ade73
complex service specs
austinmilt Apr 19, 2024
a4610be
custom schema error tests
austinmilt Apr 19, 2024
019343e
example initialization and structure
austinmilt Apr 19, 2024
7c292fd
action button to create item
austinmilt Apr 19, 2024
a0290a9
mock get items and their details
austinmilt Apr 19, 2024
45412f5
put and take items
austinmilt Apr 19, 2024
0a67c14
better add and take one item
austinmilt Apr 19, 2024
812b48d
delete an item
austinmilt Apr 19, 2024
c0ed1e3
example app with mocked backend
austinmilt Apr 19, 2024
e864b25
example tests for example frontend
austinmilt Apr 20, 2024
f6127a2
implement go example server
austinmilt Apr 20, 2024
568a5ba
switch to using dart http package for requests
austinmilt Apr 20, 2024
119ae5f
launch config for example go server
austinmilt Apr 20, 2024
c0ae937
docs on running example app
austinmilt Apr 20, 2024
caa7c45
github action for running tests
austinmilt Apr 20, 2024
0b56051
change webrpc version for github actions
austinmilt Apr 22, 2024
a490d44
fix webrpc download location in CI build
austinmilt Apr 22, 2024
e26291e
add dart dependency
austinmilt Apr 22, 2024
dbd096f
fix dart version in CI runner
austinmilt Apr 22, 2024
778fc8d
use working-directory for ci workflow
austinmilt Apr 22, 2024
bccb2a4
increase timeout of webrcp-test server to reuse existing for tests
austinmilt Apr 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Test

on:
push:
branches:
- master
pull_request:
branches:
- "**"

jobs:
get-webrpc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Install webrpc-gen
run: |
curl -o ./webrpc-gen -fLJO https://github.com/webrpc/webrpc/releases/download/v0.18.0/webrpc-gen.linux-amd64
chmod +x ./webrpc-gen
echo $PWD >> $GITHUB_PATH

webrpc-tests:
runs-on: ubuntu-latest
strategy:
matrix:
webrpc-version: [v0.18.0]
dart-version: [3.1]

steps:
- uses: actions/checkout@v3

- name: Set up webrpc binary cache folder
uses: actions/cache@v3
with:
key: webrpc-binaries
path: tests/.tmp

- uses: dart-lang/setup-dart@v1
with:
sdk: ${{ matrix.dart-version }}

- name: Download webrpc binaries
working-directory: ./tests
run: ./scripts/download.sh ${{ matrix.webrpc-version }} .tmp/

- name: Export path of webrpc binaries
working-directory: ./tests
run: echo "$PWD/.tmp" >> $GITHUB_PATH

- name: Install Dart dependencies
working-directory: ./tests
run: dart pub get

- name: Run interoperability tests
working-directory: ./tests
run: ./scripts/test.sh
47 changes: 47 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Ex. frontend (main)",
"request": "launch",
"type": "dart",
"program": "${workspaceFolder}/_examples/flutter-go/flutter_app/lib/main.dart",
"args": [
"--dart-define=SERVICE=real",
"--dart-define=SERVICE_HOSTNAME=http://localhost:3333",
"--web-browser-flag=--disable-web-security"
]
},
{
"name": "Ex. frontend (mocked)",
"request": "launch",
"type": "dart",
"program": "${workspaceFolder}/_examples/flutter-go/flutter_app/lib/main.dart",
"args": [
"--dart-define=SERVICE=mock",
"--web-browser-flag=--disable-web-security"
]
},
{
"name": "Ex. frontend tests",
"type": "dart",
"request": "launch",
"program": "${workspaceFolder}/_examples/flutter-go/flutter_app/test/",
"args": [
"--dart-define=SERVICE=mock",
]
},
{
"name": "Ex. backend (go_server)",
"request": "launch",
"type": "go",
"program": "${workspaceFolder}/_examples/flutter-go/go_server/main.go",
"env": {
"SERVICE_PORT": "3333"
}
},
]
}
20 changes: 20 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright (c) 2019-present https://github.com/webrpc authors

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
115 changes: 114 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,114 @@
# gen-dart
# gen-dart

webrpc-gen Dart templates
===============================

This repo contains the templates used by the `webrpc-gen` cli to code-generate
webrpc Dart server and client code.

This generator, from a webrpc schema/design file will code-generate:

1. Client -- an isomorphic/universal Dart client to speak to a webrpc server using the
provided schema. This client is compatible with any webrpc server language (ie. Go, nodejs, etc.).

2. Server -- not yet supported

## Dependencies
The generated client requires the standard `http` package to function. Add it to your pubspec.yaml
in your Dart or Flutter project

```
dependencies:
# ... other dependencies
http: ^1.1.0
```

## Usage

```
webrpc-gen -schema=example.ridl -target=dart -client -out=./example.gen.dart
```

or

```
webrpc-gen -schema=example.ridl -target=github.com/webrpc/[email protected] -client -out=./example.gen.dart
```

or

```
webrpc-gen -schema=example.ridl -target=./local-templates-on-disk -client -out=./example.gen.dart
```

As you can see, the `-target` supports default `dart`, any git URI, or a local folder

### Set custom template variables
Change any of the following values by passing `-option="Value"` CLI flag to `webrpc-gen`.

| webrpc-gen -option | Description | Default value |
|----------------------|----------------------------|----------------------------|
| `-client` | generate client code | unset (`false`) |
| `-server` | generate server code | unset (`false`) |

### Avoid using Records
Because Dart [Records do not retain runtime information about their structure](https://github.com/dart-lang/language/issues/2826), it's impossible
to reliably convert them to and from JSON. For this reason, we strongly advise against
using Records in schema objects that have an `any` type (which maps to `dynamic` in Dart). In fact,
you probably should not ever use the `any` type in your schema because it has ambigious
structure which makes its structure meaningless on the other end of the wire. If you need a truly
unstructured object, consider defining an internal convention and declaring it as a string in the schema.

### Handle 64-bit numbers yourself
Numbers (`double`, `num`, `int`) in Dart can have up to 64 bits of width. However, if you are
using Flutter and building for web, [numbers are limited to ~53 bits](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER). In brief,
the consequence of this is that if your server sends a JSON number that is too big, it may be
truncated - the value will change - according to the platform (language + architecture) being used.
So, if you expected to use "wide" numbers (less than -(2^53 -1) or more than 2^53 - 1), you
should package those numbers as a string and use the appropriate tools to handle them inside
your app (such as `BigInt` in Dart).

## CONTRIBUTE

### Setup
Install Dart or Flutter. Ensure your version matches the `sdk` version specified in [tests/pubspec.yaml](tests/pubspec.yaml).

Fork this repo.

Run the test scripts to ensure everything is set up correctly.
```bash
cd tests
./scripts/download.sh v0.17.2 .tmp/
./scripts/test.sh
```

Generated code will be written to [tests/lib/client.dart](tests/lib/client.dart)

### Make changes
Refer to the [webrpc generator README](https://github.com/webrpc/webrpc/tree/master/gen) for help on syntax.
In brief, start in [main.go.tmpl] and traverse the template tree by going to the template file
named by `{{template "templateName" <args>}}`, e.g. "templateName.go.tmpl".

### (Update and) Run tests
Following the typical structure for a Dart package, tests are located in the aptly named
[tests/test/](tests/test/).

### Working with a local version of webrpc?
If you are working with a local version of the base `webrpc` repo, build the generator and test server scripts
there

```bash
cd path/to/webrpc
make build build-test
```

and pass the `webrpc/bin` directory to [tests/scripts/test.sh](tests/scripts/test.sh)

```bash
cd tests
./scripts/test.sh -r path/to/webrpc/bin
```

## LICENSE

[MIT LICENSE](./LICENSE)
Empty file added _examples/flutter-go/.gitignore
Empty file.
41 changes: 41 additions & 0 deletions _examples/flutter-go/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# flutter-go
An example full-stack app using Flutter as the frontend and a minimal golang server as the backend.

## Structure

| Path | Description |
| --------------------------------------------------- | ---------- |
| [service.ridl](./service.ridl) | webrpc service schema (types, endpoints, and errors); shared between client and server. |
| [flutter_app/](./flutter_app/) | frontend Flutter app (tested on Web only) |
| [flutter_app/lib/main.dart](./flutter_app/lib/main.dart) | flutter app entry-point |
| [flutter_app/lib/generated/sdk.dart](./flutter_app/lib/generated/sdk.dart) | generated client code |
| [flutter_app/lib/dev/mock_sdk.dart](./flutter_app/lib/dev/mock_sdk.dart) | example of mocking the service for development and testing |
| [flutter_app/lib/src/sample_feature/*](./flutter_app/lib/src/sample_feature/) | widgets using the generated client |
| [flutter_app/test/widget_test.dart](./flutter_app/test/widget_test.dart) | tests of widgets using the generated client |
| [go_server/](./go_server/) | Backend server |

## Try it out
Start the server (after installing Go).
```bash
cd go_server
SERVICE_PORT=3333 go run main.go
```

Start the client (after installing Flutter).
```bash
cd flutter_app
flutter run -d chrome --dart-define=SERVICE=real --dart-define=SERVICE_HOSTNAME=http://localhost:3333
```

## Make changes
Try updating the service schema and re-generating the client and server code.

To generate the client
```bash
path/to/webrpc-gen -schema=./service.ridl -target=../../ -client -out=flutter_app/lib/generated/sdk.dart
```

To generate the server
```bash
path/to/webrpc-gen -schema=./service.ridl -target=golang -server -out=go_server/proto/server.gen.go
```
44 changes: 44 additions & 0 deletions _examples/flutter-go/flutter_app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
30 changes: 30 additions & 0 deletions _examples/flutter-go/flutter_app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# flutter_app

A new Flutter project.

## Getting Started

This project is a starting point for a Flutter application that follows the
[simple app state management
tutorial](https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple).

For help getting started with Flutter development, view the
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

## Assets

The `assets` directory houses images, fonts, and any other files you want to
include with your application.

The `assets/images` directory contains [resolution-aware
images](https://flutter.dev/docs/development/ui/assets-and-images#resolution-aware).

## Localization

This project generates localized messages based on arb files found in
the `lib/src/localization` directory.

To support additional languages, please visit the tutorial on
[Internationalizing Flutter
apps](https://flutter.dev/docs/development/accessibility-and-localization/internationalization)
28 changes: 28 additions & 0 deletions _examples/flutter-go/flutter_app/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml

linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
Loading
Loading