Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/osaxma/mid
Build an End-to-End Typesafe APIs (Experimental)
https://github.com/osaxma/mid
api backend dart flutter
Last synced: 9 days ago
JSON representation
Build an End-to-End Typesafe APIs (Experimental)
- Host: GitHub
- URL: https://github.com/osaxma/mid
- Owner: osaxma
- License: mit
- Created: 2022-08-05T14:42:12.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2022-09-19T13:04:40.000Z (over 2 years ago)
- Last Synced: 2025-01-16T17:38:25.902Z (13 days ago)
- Topics: api, backend, dart, flutter
- Language: Dart
- Homepage:
- Size: 630 KB
- Stars: 16
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# mid
> ⚠️ warning: the project is still experimental!
>
> so things may change often until a stable version is released.`mid` is a tool to build an end-to-end typesafe API in dart. The tool generates an API server and a client library in addition to handling requests and managing communication between the server and the client.
In short:
- You write this on the server side:
```dart
class App extends EndPoints {
final Database database;App(this.database);
Future getUserData(int uid) async {
final user = await database.getUserById(uid);
return user;
}Stream> timeline(int uid) {
return database.timelineStream(uid);
}Future updateProfile(UserProfile profile) {
await database.updateProfile(profile);
}
}
```- And `mid` enables you to do this on the client side:
```dart
final client = TheClient(url: 'localhost:8080');final UserData data = await client.getUserData(42);
final Stream> posts = await client.timeline(uid);
final newProfile = profile.copyWith(photoURL: photoURL);
await client.updateProfile(newProfile);
```See the [Quick Start Tutorial](https://github.com/osaxma/mid/tree/main/tutorials/quick_start/README.md) to learn how to use `mid` in no time.
## Getting Started
### Installation:
```sh
dart pub global activate mid
```### Tutorials:
- [Quick Start Tutorial](https://github.com/osaxma/mid/tree/main/tutorials/quick_start/README.md)
### Examples:
- Examples will be added **SOON** to the [examples](https://github.com/osaxma/mid/tree/main/examples) folder.
### Documentation
The documentation is being created incrementally within [docs](https://github.com/osaxma/mid/tree/main/docs) folder. Currently the following is available:- [client](https://github.com/osaxma/mid/blob/main/docs/client.md)
- [server](https://github.com/osaxma/mid/blob/main/docs/server.md)
- [interceptors](https://github.com/osaxma/mid/blob/main/docs/interceptors.md)
- [project_structure](https://github.com/osaxma/mid/blob/main/docs/project_structure.md)
- [serialization](https://github.com/osaxma/mid/blob/main/docs/serialization.md)## Motivation
To have the ability to call the backend code from the frontend in a type safe manner and as simple as calling a function in pure Dart.
> Note: `mid` is not intended to generate a REST API, but to generate an API server that can be seamlessly used by a Dart or Flutter frontend with a minimal effort.
## How does it work
`mid` simply works by converting the public methods for a given list of classes into endpoints on a [shelf][] server by generating a [shelf_router][] and its handlers. In addition, the return type and the parameters types of each method are parsed and analyzed to generate the serialization/deserialization code for each type.The client library is generated in a similar manner where each class, method, return type and parameter type is regenerated so that each endpoint becomes a simple function.
To support streaming data from the server to the client, [shelf_web_socket] is used on the server while [web_socket_channel][] on the client.
[shelf]: https://pub.dev/packages/shelf
[shelf_router]: https://pub.dev/packages/shelf_router
[shelf_web_socket]: https://pub.dev/packages/shelf_web_socket
[web_socket_channel]: https://pub.dev/packages/web_socket_channel## Additional Notes
### Supported Classes
Any class of an `EndPoints`\* type. `mid` will only expose the public methods of the given class and it'll not expose any of its superclass(es).\* `EndPoints` is just a type -- for now there's nothing to implement. a class just needs to implement, extend or mixin `EndPoints` so it can be converted.
### Supported Return Types and Method Parameters Types
- All core Types (`int`, `double`, `num`, `bool`, `String`, `DateTime`, `Duration`, `enum`, `Uri`, `BigInt`)
- User defined Classes\*
- Collections (i.e., `Map`, `Set`, `List`) of any of the above.
- `Future` or `Stream` for any of the above.\* `mid` is able to serialize user defined classes and their members recursively as long as they have an unnamed generative constructor with formal parameters only (i.e. all parameters using `this`). An example class would be:
```dart
class UserData {
final int id;
final String name;
final bool isAdmin;
// `MetaData` must follow the same rules including its members.
final MetaData? metadata;
// this is what `mid` is looking for (i.e. no assignment in initializer list or constructor body):
UserData({
required this.id,
required this.name,
this.metadata,
this.isAdmin = false,
});
/* you can define your own methods, factory constructors, and whatnot */
}
```