MAUI Embedded Web Architecture 실전 적용 (2) PicoServer 라우팅 메커니즘 및 API 설계
Source: Dev.to
I. 전체 아키텍처
.NET MAUI 애플리케이션에 PicoServer를 임베드하면 다음과 같은 임베디드‑웹 아키텍처를 구성할 수 있습니다:
Browser / WebView
│
HTTP
│
┌────────────┐
│ PicoServer │
└────────────┘
│
┌──────────────┼──────────────┐
│ │
REST API Web Admin
│ │
└──────────────┬──────────────┘
│
Service Layer
│
MAUI App
- PicoServer – HTTP 요청을 처리합니다.
- REST API – 데이터 인터페이스를 제공합니다.
- Web Admin – 관리 인터페이스를 제공합니다.
- Service Layer – 비즈니스 로직을 포함합니다.
- MAUI App – 디바이스 기능 및 로컬 기능을 관리합니다.
이 패턴을 사용하면 모바일 또는 데스크톱 애플리케이션에 웹‑서버 기능을 동시에 장착할 수 있습니다.
II. “Hello PicoServer”에서 API 서버로
이전 글 Practical Combat of MAUI Embedded Web Architecture (I) 에서 기본 환경 설정을 마쳤습니다:
- MAUI에 Embedded PicoServer 삽입
- 로컬 HTTP 서비스 실행
브라우저를 통한 접근:
응답:
Hello PicoServer
이제 애플리케이션은 로컬 웹 서버 기능을 갖추었습니다.
실제 프로젝트에서는 단순 문자열 응답만으로는 부족합니다. 실용적인 로컬 웹 서비스는 일반적으로 다음을 필요로 합니다:
- REST API
- JSON 데이터 인터페이스
- 디바이스 제어 인터페이스
- 로컬 웹 관리 백엔드
이 글에서는 PicoServer의 라우팅 메커니즘과 API 설계 방법에 초점을 맞추어, 샘플 서버를 실제로 사용할 수 있는 로컬 API 서비스로 업그레이드합니다.
III. 라우트란 무엇인가?
In a web server, a route defines the mapping between URLs and handler functions, e.g.:
| URL | 처리 로직 |
|---|---|
/ | 홈페이지 |
/api/time | 서버 시간 반환 |
/api/device/list | 디바이스 목록 반환 |
When a browser accesses a route, the processing flow is:
Browser
│
HTTP Request
│
/api/time
│
PicoServer Router
│
Handler Method
│
JSON Response
The routing system is a core component of any web service.
라우팅 시스템은 모든 웹 서비스의 핵심 구성 요소입니다.
IV. PicoServer 라우팅 기본 사용법
첫 번째 기사에서 우리는 이미 가장 간단한 라우트를 사용했습니다:
MyAPI.AddRoute("/", Hello);
전체 예제
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");
}
}
라우트 매핑:
/ → Hello()
/에 접속하면 Hello()가 실행됩니다.
V. 여러 API 라우트 추가
실제 프로젝트에서는 보통 다음과 같은 여러 API가 필요합니다:
- 서버 시간 가져오기
- 시스템 상태 조회
- 디바이스 목록 가져오기
여러 라우트를 정의합니다:
public PicoAdmin()
{
MyAPI.AddRoute("/", Hello);
MyAPI.AddRoute("/api/time", GetTime);
MyAPI.AddRoute("/api/status", GetStatus);
MyAPI.StartServer();
}
핸들러를 구현합니다:
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");
}
샘플 응답
2026/3/5 14:30:12
VI. RESTful API 설계
현대 웹 시스템은 보통 RESTful API를 채택합니다. 예시:
| API | 기능 |
|---|---|
GET /api/product/list | 제품 목록 |
GET /api/product/detail?id=1 | 제품 상세 |
POST /api/product/add | 새 제품 추가 |
장점:
- 명확한 인터페이스 의미
- 확장 가능한 구조
- 프론트엔드 호출이 용이
PicoServer에서 이를 다음과 같이 표현할 수 있다:
MyAPI.AddRoute("/api/product/list", ProductList);
MyAPI.AddRoute("/api/product/detail", ProductDetail);
VII. JSON 데이터 반환
실용적인 API는 일반 문자열보다 JSON을 반환하는 경우가 많습니다, 예:
{
"code": 0,
"message": "ok",
"data": {
"time": "2026-03-05 14:30:00"
}
}
C# 구현:
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);
}
VIII. GET 매개변수 읽기
많은 API는 다음과 같은 요청 매개변수를 읽어야 합니다:
/api/product/detail?id=1001
매개변수는 다음과 같이 얻을 수 있습니다:
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);
}
접근 주소:
http://127.0.0.1:8090/api/product/detail?id=1001
받은 응답:
{
"id": "1001",
"name": "Demo Product",
"price": 100
}
IX. 제품 목록 API 예제
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);
}
접근 주소:
http://127.0.0.1:8090/api/product/list
받은 응답:
{
"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 }
]
}
X. API 라우팅 설계 권장 사항
로컬 API를 설계할 때는 다음 규칙을 따르세요:
1. 통합 API 프리픽스
공통 프리픽스를 사용합니다, 예: /api/*.
예시
GET /api/product/listGET /api/product/detail?id=1POST /api/product/addDELETE /api/product/delete?id=1
HTTP 메서드 설명
| Method | 동작 |
|---|---|
| GET | Query |
| POST | Create |
| PUT | Update |
| DELETE | Delete |
2. 통합 응답 구조
일관된 JSON 형식을 채택합니다:
{
"code": 0,
"message": "ok",
"data": {}
}
장점
- 통합된 프론트엔드 처리
- 간단한 오류 처리
- 명확한 인터페이스 사양
3. API 모듈 그룹화
비즈니스 모듈별로 API를 그룹화합니다:
/api/system/*/api/device/*/api/product/*
이렇게 하면 인터페이스 구조가 명확하고 유지보수가 쉬워집니다.
XI. 로컬 API의 전형적인 적용 시나리오
앱 내부에서 HTTP 서버가 실행될 때, 다양한 아키텍처 패턴이 가능해집니다.
1. 로컬 웹 관리자
Browser
↓
localhost:8090
↓
PicoServer API
↓
MAUI Local Logic
2. WebView + 로컬 API
WebView Page
↓
fetch("/api/product/list")
↓
PicoServer
↓
C# Business Logic
3. LAN 디바이스 제어
Mobile Phone / PC
↓
http://192.168.1.100:8090
↓
Device Control API
공통 시나리오
- IoT 디바이스 관리
- 데스크톱 소프트웨어 백엔드
- 로컬 콘솔 유틸리티
- 디버깅 인터페이스
XII. 이 기사 요약
이 기사에서는 세 가지 핵심 단계를 완료했습니다:
- PicoServer 라우팅 메커니즘 이해
- 다중 API 인터페이스 구축
- 표준 JSON 데이터 반환
우리는 초기 **“Hello PicoServer”**를 실제로 사용할 수 있는 로컬 REST API 서비스로 업그레이드했습니다.
다음 기사 미리보기
MAUI 임베디드 웹 아키텍처 실전 (III): 확장 가능한 PicoServer REST API 프레임워크 구축
포함 내용:
- 컨트롤러 구조 설계
- 서비스 레이어 아키텍처
- 통합 API 응답 모델
- 전역 예외 처리
- 로깅 시스템
궁극적인 목표는 확장 가능한 임베디드 API 프레임워크를 구축하는 것입니다.
Series Articles
- Embedding PicoServer in MAUI
- PicoServer Routing Mechanism and API Design
- Building a Scalable REST API Framework
- Static File Hosting and Frontend Integration
- Building a Web Admin Backend
- Login Authentication and Permission System
- LAN Access and Device Management
- Local Cache Architecture
- PicoServer + PWA Offline System
- Complete App Web Shell Architecture