DEV Community

Cover image for I Built Fast API, but for Flutter/Dart & AI
Dylan Scott Mickelson
Dylan Scott Mickelson

Posted on

I Built Fast API, but for Flutter/Dart & AI

One of my favorite Python Packages is fastapi. I love how you can build an API server very quickly with minimal code. Then, to top it off, you can use its built-in Swagger UI to test your API.

🚨 The Problem:

To my knowledge, Flutter/Dart has no package that does this...

💡 The Solution:

I will build it myself...

❓ But why build a package like this in the first place?

You got me! It was really to connect AI Agents to my Flutter applications- why, of course!

Build It GIF

🏗️ How I built it...

  • I did not build this package from the ground up; I had some help!

  • Introducing shelf, a web-server middleware package for Dart.

  • I used shelf to create a Flutter package named fast_crud_api.

  • fast_crud_api is a lightweight, simple, and customizable CRUD API Server in Dart.

CRUD Futurama GIF

💾 What is CRUD, and why is it a part of the package?

CRUD is an acronym for Create, Read, Update, and Delete, representing the four fundamental operations for managing persistent data in software applications and databases.

I built CRUD into the package because it creates a pathway for an AI Agent to control specific app functionality. With four endpoints (/create, /read, /update, and /delete).

For example, if I created a notes app in Flutter. With fast_crud_api, I could connect an AI Agent to create, read, update, and delete notes. Effectively giving the AI Agent a new skill that it can use.

Likewise, you could leave the CRUD out of it and create a custom API instead!

Under The Hood Cat In the Hat GIF

🚘 Let's look under the hood and see how it works...

  • APIServer is the main implementation and has the following parameters:
class APIServer {
  final String? apiName;
  final Future<Response> Function(Request)? create;
  final Future<Response> Function(Request)? read;
  final Future<Response> Function(Request)? update;
  final Future<Response> Function(Request)? delete;
  final int? port;
  final int? version;
  final List<CustomRoute>? routes;
  final bool? noCRUD;
  final bool? logger;

  APIServer({
    this.create,
    this.read,
    this.update,
    this.delete,
    this.port,
    this.version,
    this.apiName,
    this.routes,
    this.noCRUD,
    this.logger,
  });
}
Enter fullscreen mode Exit fullscreen mode
  • It has one function named start() that creates and starts the API server.

Now let's add fast_crud_api to your Flutter or Dart project.

🆕 How to add fast_crud_api to your Flutter/Dart app:

  • Add fast_crud_api and shelf to your pubspec.yaml file:
dependencies:
  shelf: any
  fast_crud_api:
    git:
      url: https://github.com/DylanScottMickelson/fast_crud_api.git
Enter fullscreen mode Exit fullscreen mode
  • Now, run flutter pub get or dart pub get in your terminal/command prompt to install the package and its dependencies.

  • Add this example code inside your main.dart file:


import 'package:fast_crud_api/fast_crud_api.dart';
import 'package:shelf/shelf.dart';

void main() async {
  /// Define your create, read, update, and delete functions here...
  Future<Response> createFunction(Request request) async {
    return Response.ok("Created!");
  }

  Future<Response> readFunction(Request request) async {
    return Response.ok("Read!");
  }

  Future<Response> updateFunction(Request request) async {
    return Response.ok("Updated!");
  }

  Future<Response> deleteFunction(Request request) async {
    return Response.ok("Deleted!");
  }
  /// Create API Server Implementation
  final apiServer = APIServer(
    create: (request) => createFunction(request),
    read: (request) => readFunction(request),
    update: (request) => updateFunction(request),
    delete: (request) => deleteFunction(request),
    port: 6969,
    version: 1,
    apiName: "My API",
    noCRUD: false,
    logger: true,
  );
  ///Start API Server
  await apiServer.start();
}

Enter fullscreen mode Exit fullscreen mode
  • Use CRUD and Custom Routes
import 'package:fast_crud_api/custom_route.dart';
import 'package:fast_crud_api/fast_crud_api.dart';
import 'package:shelf/shelf.dart';

void main() async {
  final handler = Response.notFound;

  /// Define your create, read, update, and delete functions here...
  Future<Response> createFunction(Request request) {
    return Response.ok("Created!");
  }

  Future<Response> readFunction(Request request) {
    return Response.ok("Read!");
  }

  Future<Response> updateFunction(Request request) {
    return Response.ok("Updated!");
  }

  Future<Response> deleteFunction(Request request) {
    return Response.ok("Deleted!");
  }


  /// Define your custom endpoints here...
  final customRoute1 = CustomRoute(
    endpoint: "users",
    method: "GET",
    handler: (request) => Response.ok("Users Read!"),
  );

  final apiServer = APIServer(
    create: (request) => createFunction(request),
    read: (request) => readFunction(request),
    update: (request) => updateFunction(request),
    delete: (request) => deleteFunction(request),
    port: 6969,
    version: 1,
    apiName: "My API",
    noCRUD: false,
    logger: true,
    routes: [customRoute1],
  );

  await apiServer.start();
}

Enter fullscreen mode Exit fullscreen mode
  • Turn Off CRUD and Use Only Custom Routes

import 'dart:convert';

import 'package:fast_crud_api/custom_route.dart';
import 'package:fast_crud_api/fast_crud_api.dart';
import 'package:shelf/shelf.dart';

void main() async {
  /// Define your custom endpoints here...
  final customRoute1 = CustomRoute(
    endpoint: "users",
    method: "GET",
    handler: (request) => Response.ok(jsonEncode({"users": []})),
  );

  final apiServer = APIServer(
    port: 6969,
    version: 1,
    apiName: "My API",
    noCRUD: true,
    logger: true,
    routes: [customRoute1],
  );

  await apiServer.start();
}

Enter fullscreen mode Exit fullscreen mode

👨‍💻 Access and Use the API

  • 🪟 API Docs UI Fast CRUD API Docs UI

Production:
Go to http://ip_address:chosen_port/api/docs/

Test:
Go to http://127.0.0.1:6969/api/docs/

  • 🌐 HTTP / CURL Request

Production:

Test:

🌯 Wrapping Up

Building an efficient backend layer for a modern application can often feel like solving multiple puzzles at once. But with fast_crud_api, that process is streamlined significantly.

By leveraging Dart's power and the shelf package, fast_crud_api provides developers with a lightweight, and customizable API server.

The key takeaway isn't just how to set up an API server in Flutter/Dart, but what you can do with it. Namely, giving AI Agents standardized, reliable endpoints (Create, Read, Update, Delete) that allow them to interact with your application data seamlessly.

I hope this walkthrough was helpful! Comment and let me know what you think, or dive into the code in the GitHub repo.
Happy coding! 🧑‍💻

Top comments (0)