DEV Community

ben
ben

Posted on

Practical Combat of MAUI Embedded Web Architecture (2)PicoServer Routing Mechanism and API Design

PicoServer
Source Code URL:
https://github.com/densen2014/MauiPicoAdmin

I. Overall Architecture

After embedding PicoServer in a .NET MAUI application, the following embedded web architecture can be formed:

                Browser / WebView
                       │
                    HTTP
                       │
                ┌────────────┐
                │ PicoServer │
                └────────────┘
                       │
        ┌──────────────┼──────────────┐
        │                             │
     REST API                     Web Admin
        │                             │
        └──────────────┬──────────────┘
                       │
                   Service Layer
                       │
                    MAUI App
Enter fullscreen mode Exit fullscreen mode

In this architecture:

  • PicoServer is responsible for handling HTTP requests.
  • REST API provides data interfaces.
  • Web Admin offers an administration interface.
  • Service Layer takes charge of business logic.
  • MAUI App manages device capabilities and local functions.

This pattern enables a mobile or desktop application to be equipped with web server capabilities simultaneously.

II. From Hello PicoServer to API Server

In the previous article Practical Combat of MAUI Embedded Web Architecture (I), we have completed the basic environment setup:

  1. Embed PicoServer in MAUI
  2. Launch the local HTTP service
  3. Access via browser: http://127.0.0.1:8090
  4. Response received:
   Hello PicoServer
Enter fullscreen mode Exit fullscreen mode

This indicates that our application has gained the capability of a local web server.

However, in real-world projects, simply returning a string is far from enough.

A truly usable local web service typically requires:

  • REST API
  • JSON data interfaces
  • Device control interfaces
  • Local web administration backend

Therefore, this article will focus on:
The routing mechanism and API design methods of PicoServer

and upgrade the sample server into a truly usable local API service.

III. What is a Route?

In a web server, a Route is used to define:
The mapping relationship between URLs and handler functions.

For example:

URL Processing Logic
/ Homepage
/api/time Return server time
/api/device/list Return device list

When a browser accesses the address:
http://127.0.0.1:8090/api/time

The server processing flow is as follows:

Browser
   │
HTTP Request
   │
/api/time
   │
PicoServer Router
   │
Handler Method
   │
JSON Response
Enter fullscreen mode Exit fullscreen mode

Thus, the routing system is one of the core components of a web service.

IV. Basic Usage of PicoServer Routing

In the sample from the first article, we already used the simplest route:

MyAPI.AddRoute("/", Hello);
Enter fullscreen mode Exit fullscreen mode

The complete code is as follows:

public class PicoAdmin
{
    private readonly WebAPIServer MyAPI = new WebAPIServer();

    public PicoAdmin()
    {
        MyAPI.AddRoute("/", Hello);
        MyAPI.StartServer();
    }

    private async Task Hello(HttpListenerRequest request, HttpListenerResponse response)
    {
        await response.WriteAsync("Hello PicoServer");
    }
}
Enter fullscreen mode Exit fullscreen mode

Route mapping relationship:
/ → Hello()

When accessing /, the Hello() method will be executed.

V. Adding Multiple API Routes

In practical projects, we usually need multiple APIs, such as:

  • Get server time
  • Query system status
  • Retrieve device list

Multiple routes can be defined like this:

public PicoAdmin()
{
    MyAPI.AddRoute("/", Hello);
    MyAPI.AddRoute("/api/time", GetTime);
    MyAPI.AddRoute("/api/status", GetStatus);

    MyAPI.StartServer();
}
Enter fullscreen mode Exit fullscreen mode

Implement the corresponding interfaces:

private async Task GetTime(HttpListenerRequest request, HttpListenerResponse response)
{
    var time = DateTime.Now.ToString();
    await response.WriteAsync(time);
}

private async Task GetStatus(HttpListenerRequest request, HttpListenerResponse response)
{
    await response.WriteAsync("Server Running");
}
Enter fullscreen mode Exit fullscreen mode

Access address:
http://127.0.0.1:8090/api/time

Sample response:

2026/3/5 14:30:12
Enter fullscreen mode Exit fullscreen mode

VI. Designing RESTful APIs

Modern web systems usually adopt RESTful APIs.

For example:

API Function
GET /api/product/list Product list
GET /api/product/detail?id=1 Product details
POST /api/product/add Add new product

This design has the following advantages:

  • Clear interface semantics
  • Scalable structure
  • Convenient for front-end invocation

It can be designed in PicoServer like this:

MyAPI.AddRoute("/api/product/list", ProductList);
MyAPI.AddRoute("/api/product/detail", ProductDetail);
Enter fullscreen mode Exit fullscreen mode

VII. Returning JSON Data

Practical APIs usually return JSON data instead of simple strings.

For example:

{
  "code": 0,
  "message": "ok",
  "data": {
    "time": "2026-03-05 14:30:00"
  }
}
Enter fullscreen mode Exit fullscreen mode

It can be implemented in C# like this:

private async Task GetTime(HttpListenerRequest request, HttpListenerResponse response)
{
    var result = new
    {
        code = 0,
        message = "ok",
        data = new
        {
            time = DateTime.Now
        }
    };

    string json = System.Text.Json.JsonSerializer.Serialize(result);

    response.ContentType = "application/json";
    await response.WriteAsync(json);
}
Enter fullscreen mode Exit fullscreen mode

Access address:
http://127.0.0.1:8090/api/time

Response received:

{
  "code":0,
  "message":"ok",
  "data":{
    "time":"2026-03-05T14:30:00"
  }
}
Enter fullscreen mode Exit fullscreen mode

With this, a standard REST API is completed.

VIII. Reading GET Parameters

Many APIs need to read request parameters, such as:
/api/product/detail?id=1001

Parameters can be obtained like this:

private async Task ProductDetail(HttpListenerRequest request, HttpListenerResponse response)
{
    string id = request.QueryString["id"];

    var result = new
    {
        id = id,
        name = "Demo Product",
        price = 100
    };

    string json = JsonSerializer.Serialize(result);

    response.ContentType = "application/json";
    await response.WriteAsync(json);
}
Enter fullscreen mode Exit fullscreen mode

Access address:
http://127.0.0.1:8090/api/product/detail?id=1001

Response received:

{
  "id":"1001",
  "name":"Demo Product",
  "price":100
}
Enter fullscreen mode Exit fullscreen mode

IX. Product List API Example

private async Task ProductList(HttpListenerRequest request, HttpListenerResponse response)
{
    var products = new[]
    {
        new { id = "1", name = "Demo Product 1", price = 100 },
        new { id = "2", name = "Demo Product 2", price = 200 },
        new { id = "3", name = "Demo Product 3", price = 300 }
    };

    var result = new
    {
        code = 0,
        message = "ok",
        data = products
    };

    string json = JsonSerializer.Serialize(result);

    response.ContentType = "application/json";
    await response.WriteAsync(json);
}
Enter fullscreen mode Exit fullscreen mode

Access address:
http://127.0.0.1:8090/api/product/list

Response received:

{
  "code": 0,
  "message": "ok",
  "data": [
    { "id": "1", "name": "Demo Product 1", "price": 100 },
    { "id": "2", "name": "Demo Product 2", "price": 200 },
    { "id": "3", "name": "Demo Product 3", "price": 300 }
  ]
}
Enter fullscreen mode Exit fullscreen mode

X. API Routing Design Recommendations

When designing local APIs, it is recommended to follow these rules:

1. Unified API Prefix

It is recommended to use a unified prefix:
/api/*

Examples:

  • GET /api/product/list
  • GET /api/product/detail?id=1
  • POST /api/product/add
  • DELETE /api/product/delete?id=1

HTTP Method Description:

  • GET Query
  • POST Create
  • PUT Update
  • DELETE Delete

2. Unified Response Structure

It is recommended to use a unified JSON response format:

{
  "code":0,
  "message":"ok",
  "data":{}
}
Enter fullscreen mode Exit fullscreen mode

Advantages:

  • Unified front-end processing
  • Simple error handling
  • Clear interface specifications

3. API Module Grouping

It is recommended to group APIs by business modules:

  • /api/system/*
  • /api/device/*
  • /api/product/*

This keeps the interface structure clear and easy to maintain.

XI. Typical Application Scenarios of Local APIs

When an HTTP server runs inside an app, many interesting architectural patterns can be implemented.

Local Web Admin

Browser
   ↓
localhost:8090
   ↓
PicoServer API
   ↓
MAUI Local Logic
Enter fullscreen mode Exit fullscreen mode

WebView + Local API

WebView Page
     ↓
fetch("/api/product/list")
     ↓
PicoServer
     ↓
C# Business Logic
Enter fullscreen mode Exit fullscreen mode

LAN Device Control

Mobile Phone / PC
     ↓
http://192.168.1.100:8090
     ↓
Device Control API
Enter fullscreen mode Exit fullscreen mode

This pattern is very common in the following scenarios:

  • IoT device management
  • Desktop software backend
  • Local console
  • Debugging interfaces

XII. Summary of This Article

In this article, we have completed three key steps:

  1. Understanding the PicoServer routing mechanism
  2. Building multiple API interfaces
  3. Returning standard JSON data

So far, we have upgraded the initial
Hello PicoServer
to
a truly usable local REST API service.

Next Article Preview

In the next article, we will continue to upgrade the architecture with:
Practical Combat of MAUI Embedded Web Architecture (III): Building a Scalable PicoServer REST API Framework

Content will include:

  • Controller structure design
  • Service layer architecture
  • Unified API response model
  • Global exception handling
  • Logging system

The ultimate goal is to build a scalable embedded API framework.

Series Articles

  1. Embedding PicoServer in MAUI
  2. PicoServer Routing Mechanism and API Design
  3. Building a Scalable REST API Framework
  4. Static File Hosting and Frontend Integration
  5. Building a Web Admin Backend
  6. Login Authentication and Permission System
  7. LAN Access and Device Management
  8. Local Cache Architecture
  9. PicoServer + PWA Offline System
  10. Complete App Web Shell Architecture

Top comments (0)