mid 0.0.1 copy "mid: ^0.0.1" to clipboard
mid: ^0.0.1 copied to clipboard

outdated

an API generation tool

mid - build end-to-end type-safe APIs (Experimental) #

⚠️ warning: The project is experimental! ⚠️

mid is a tool to build an end-to-end type-safe API. The tool generates an API server and a client library as well as handling requests and managing the communication between the server and the client.

mid simply works by converting the public methods for a given list of classes into endpoints (i.e. /class_name/method_name). The return type and the parameters of each method are parsed to generate the requests handlers, the serialization/deserialization code and the client library to be directly used by the frontend -- as simple as calling functions.

For example:

  • you write this on the server side:

    class App {
        final Database database;
    
        App(this.database);
    
        Future<UserData> getUserData(int uid) async {
            final user = await database.getUserById(uid);
            return user;
        }
    }
    
  • you will be able to do this on the client side:

    final client = AppClient(url: 'localhost:8080');
    
    final UserData data = await client.getUserData(42); 
    

In order for mid to generate the server side and client side code, the endpoints must be provided in the following manner:

Future<List<Object>> endpoints(Logger logger) async {
    final database = Database(url: String.fromEnvironment('DATABASE_URL'));
    return [
       App(apiKey: apiKey, database: database, logger: logger);,
    ];
}

One can also create multiple routes and endpoints such as:

Future<List<Object>> endpoints(Logger logger) async {
    final database = Database(url: String.fromEnvironment('DATABASE_URL'));
    final storageURL = String.fromEnvironment('STORAGE_KEY');
    final apiKey = String.fromEnvironment('API_KEY');

    final authAPI =  Auth(database: database, logger: logger);

    final storageAPI = Storage(apiKey: apiKey, url: storageURL, database: database, logger: logger);

    final applicationAPI = App(apiKey: apiKey, database: database, logger: logger);

    return [
        authAPI,
        storageAPI,
        applicationAPI,
    ];
}

For more details, see Getting Started or Examples and see the Caveats below.

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.

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.

Getting Started #

  1. Install mid:

    dart pub global activate mid
    
  2. Create a mid project:

    mid create <project_name>
    

    This will create two dart projects in the following structure:

    <project_name>
          |- <project_name>_client
          |- <project_name>_server
    
  3. open <project_name>/<project_name>_server/mid/endpoints.dart and add your endpoints there.

    You can create the endpoints classes inside the lib folder, and then import them to the endpoints file.

  4. Generate endpoints:

    mid generate endpoints 
    

    This will generate the server side code on top of shelf server within mid folder.

  5. Generate teh client code

    mid generate client 
    

Examples #

Examples will be added soon to the examples folder.

Caveats #

Supported Classes #

Any class. mid will only expose the public methods of the given class and it'll not expose any of its superclass(es).

Supported Return Types and Method Parameters Types #

  • All core Types (int, double, num, bool, String, DateTime, Duration, etc.)
  • User defined Classes*
  • Collections (i.e., Map, Set, List) of the Basic Types or Data Classes.
  • Future or Stream (not supported yet) 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:

class UserData {
    final int id;
    final String name;
    // `MetaData` will be serialized even if it doesn't appear in any method return type or parameters types
    final MetaData metadata; 
    
    // Must have unnamed generative constructor with formal parameters (i.e. using `this`). 
    UserData({this.id, this.name, this.metadata});  

    /* 
        you can define your own methods, factory constructors, and whatnot 
    */
}

6
likes
0
points
2
downloads

Publisher

verified publisherosaxma.com

Weekly Downloads

an API generation tool

Homepage

License

unknown (license)

Dependencies

analyzer, args, built_collection, cli_util, code_builder, dart_style, path

More

Packages that depend on mid