Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

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)

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 */
}
```