micro_serve 1.0.11 copy "micro_serve: ^1.0.11" to clipboard
micro_serve: ^1.0.11 copied to clipboard

A Flutter package initializes an HTTP server to handle HTTP requests.

example/lib/main.dart

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:micro_serve/micro_serve.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Micro Serve',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.deepPurple,
        ),
        useMaterial3: false,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final Map<int, Task> _taskStore = {};

  final MicroServe _server = MicroServe();

  ///SERVER ON
  void _serverOn() async {
    //Define Route
    _server.get("/", _welcome);
    _server.post("/create", _createTask);
    _server.get("/read", _readTasks);
    _server.put("/update", _updateTask);
    _server.delete("/delete", _deleteTask);

    //Get WiFi IP Address
    final String? lanWifiIp = await Network.getIp(NetworkType.wlan);
    const int port = 3000;

    //Server Start
    _server.listen(
      ipAddress: lanWifiIp,
      port: port,
      callBack: (isServerInitiated) {
        if (isServerInitiated) {
          setState(() {});
        } else {
          // print("Some thing went wrong");
        }
      },
    );
  }

  ///Server Off
  void _serverOff() async {
    await _server.close();
    setState(() {});
  }

  ///HANDLER FUNCTION
  void _welcome(ServerContext serverContext) async {
    Response response = Response(
      statusCode: 200,
      data: {
        "message": "Server is Running...",
        "clientIp": serverContext.connectionInfo.address,
      },
    );
    serverContext.send(response);
  }

  void _createTask(ServerContext serverContext) async {
    final Request request = serverContext.request;
    final Task newTask = Task.fromJson(jsonDecode(request.body));

    Response response = Response();
    if (_taskStore.containsKey(newTask.id)) {
      response.statusCode = HttpStatus.conflict_409.code;
      response.data = {"message": "already exist"};
    } else {
      _taskStore[newTask.id] = newTask;
      final Map responseBody = {
        "message": "created successfully",
        "total": _taskStore.length,
      };
      response.statusCode = HttpStatus.created_201.code;
      response.data = responseBody;
    }

    serverContext.send(response);
  }

  void _readTasks(ServerContext serverContext) async {
    final List<Map> taskList = [];

    for (Task task in _taskStore.values) {
      taskList.add(task.toJson());
    }

    final Map data = {
      "message": "fetched successfully",
      "data": taskList,
    };
    Response response = Response(
      statusCode: HttpStatus.ok_200.code,
      data: data,
    );

    serverContext.send(response);
  }

  void _updateTask(ServerContext serverContext) async {
    //Get Client Request From Request() Of ServerContext
    final Request request = serverContext.request;

    final int id = int.parse(request.queryParams["id"]!);
    final String name = jsonDecode(request.body)["name"];
    final bool isDone = jsonDecode(request.body)["isDone"];
    final String? apiKey = request.headers["api-key"];

    // print("Client IP: ${serverContext.connectionInfo.address}");

    //Create an Object of Response() to Send Client
    final Response response = Response();

    if (apiKey != "abcd1234") {
      //Edit Response Object as Preference 1
      response.statusCode = HttpStatus.unauthorized_401.code;
      response.data = {"message": "invalid api key"};
    } else if (!_taskStore.containsKey(id)) {
      //Edit Response Object as Preference 2
      response.statusCode = HttpStatus.notFound_404.code;
      response.data = {"message": "not found"};
    } else {
      _taskStore[id]!.name = name;
      _taskStore[id]!.isDone = isDone;

      //Edit Response Object as Preference 3
      response.statusCode = HttpStatus.accepted_202.code;
      response.data = {"message": "updated successfully"};
    }

    //Send Response to Client
    serverContext.send(response);
  }

  void _deleteTask(ServerContext serverContext) async {
    final Request request = serverContext.request;
    final int taskId = int.parse(request.queryParams["id"]!);

    final Response response = Response();
    if (!_taskStore.containsKey(taskId)) {
      response.statusCode = HttpStatus.notFound_404.code;
      response.data = {"message": "not found"};
    } else {
      _taskStore.remove(taskId);

      final Map responseBody = {
        "message": "deleted successfully",
        "total": _taskStore.length,
      };
      response.statusCode = HttpStatus.accepted_202.code;
      response.data = responseBody;
    }

    serverContext.send(response);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Micro Serve"),
      ),
      body: Column(
        children: [
          Flexible(
            flex: 1,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                _server.info.isRunning
                    ? Text(
                        "Server running on...\nhttp://${_server.info.address}:${_server.info.port}/",
                        textAlign: TextAlign.center,
                      )
                    : const Text("Server is offline now"),
                ElevatedButton(
                  onPressed: !_server.info.isRunning ? _serverOn : _serverOff,
                  child: Text(!_server.info.isRunning ? "Tap To Start" : "Stop"),
                ),
              ],
            ),
          ),
          Flexible(
            flex: 4,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Text("API REFERENCE"),
                _textWidget(welcome),
                _textWidget(createTask),
                _textWidget(readTasks),
                _textWidget(updateTask),
                _textWidget(deleteTask),
              ],
            ),
          ),
        ],
      ),
    );
  }

  ///API REFERENCE
  final String welcome = '''
[GET]\thttp://ip:port/''';

  final String createTask = '''
[POST]\thttp://ip:port/create

body:
{
  "id" : 1,
  "name" : "first task",
  "isDone" : false
}''';
  final String readTasks = '''
[GET]\thttp://ip:port/read''';
  final String updateTask = '''
[PUT]\thttp://ip:port/update?id=1

body:
{
  "name" : "mh task",
  "isDone" : true
}''';
  final String deleteTask = '''
[DELETE]\thttp://ip:port/delete?id=1''';

  Widget _textWidget(String text) {
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.all(8),
      margin: const EdgeInsets.all(8),
      decoration: BoxDecoration(border: Border.all()),
      child: SelectableText(
        text,
      ),
    );
  }
}

///TASK MODEL
class Task {
  int id;
  String name;
  bool isDone;

  Task({
    required this.id,
    required this.name,
    required this.isDone,
  });

  factory Task.fromJson(Map<String, dynamic> json) => Task(
        id: json["id"],
        name: json["name"],
        isDone: json["isDone"],
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "isDone": isDone,
      };
}
6
likes
150
points
41
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter package initializes an HTTP server to handle HTTP requests.

Homepage
Repository (GitHub)

Documentation

API reference

License

MIT (license)

More

Packages that depend on micro_serve