WatchYourLAN HTTP API 完全指南:REST 接口、参数说明与源码级实现解析
【免费下载链接】WatchYourLANLightweight network IP scanner written in Go. With notifications, history, export to Grafana项目地址: https://gitcode.com/GitHub_Trending/wa/WatchYourLAN
本指南基于 WatchYourLAN(用 Go 编写的轻量级网络 IP 扫描器)官方文档 docs/API.md 展开,系统梳理其内置 HTTP REST API 的全部端点、参数语义与返回值,并结合仓库源码剖析每个接口背后的实现链路。读完本文,你将能够直接用curl或任意编程语言调用 WatchYourLAN 完成主机查询、历史追溯、端口探测、状态统计、通知测试等操作,并理解这些接口在数据库层与扫描引擎层是如何工作的。
1. API 概览:路由注册、基础路径与 Swagger
WatchYourLAN 的后端基于 Gin 框架,所有 API 路由集中在 backend/internal/api/routes.go 的Routes函数中注册,统一挂在/api分组下:
- 主机类:
/all、/edit/:id/:name/*known、/host/:id、/host/del/:id、/host/add/:mac - 历史类:
/history、/history/:mac、/history/:mac/:date - 网络类:
/port/:addr/:port、/wol/:mac - 系统类:
/config、/notify_test、/status/*iface、/version、/rescan - 配置类(POST):
/config/、/config_settings/、/config_influx/、/config_prometheus/
同时,backend/internal/api/routes.go 通过ginSwagger.WrapHandler将 Swagger UI 挂载在/swagger/*any路径下,Swagger 规范文件位于 backend/docs/swagger.json 与 backend/docs/swagger.yaml。根据 backend/cmd/WatchYourLAN/main.go 中的注解,API 的BasePath为/api/,版本为0.1,采用 MIT 开源协议。
默认监听端口为8840:前端 frontend/src/functions/api.ts 中apiPath = 'http://0.0.0.0:8840',官方文档的请求示例同样使用0.0.0.0:8840。若需为 API 增加访问认证,仓库提供了带 Basic Auth 的部署方式(见 docker-compose-auth.yml)。
注意:本文档中的大部分接口为
GET请求,但其中部分(如/api/edit/、/api/host/del/)会产生数据变更副作用,属于"通过 GET 触发的写操作",在使用时应将其视为写接口对待。
2. 主机查询类接口
2.1GET /api/all—— 返回全部主机
GET /api/all返回当前扫描结果("now" 表)中的全部主机,格式为 JSON 数组。对应实现见 backend/internal/api/api-hosts.go:getAllHosts直接调用gdb.Select("now")取出当前在线主机快照(数据表语义见 backend/internal/gdb/select.go)。
响应中每个主机的字段由 backend/internal/models/models.go 的Host结构定义:
| 字段 | 类型 | 含义 |
|---|---|---|
ID | int | 主机唯一 ID(主键) |
Name | string | 用户自定义名称 |
DNS | string | 反向 DNS 解析结果 |
Iface | string | 所属网卡接口名 |
IP | string | IP 地址 |
Mac | string | MAC 地址 |
Hw | string | 硬件厂商信息 |
Date | string | 记录时间(如2025-09-06 00:58:26) |
Known | int | 是否已知(1已知,0未知) |
Now | int | 当前是否在线(1在线,0离线) |
示例响应:
[ { "ID": 1, "Name": "router", "DNS": "gateway.local", "Iface": "eth0", "IP": "192.168.1.1", "Mac": "aa:bb:cc:dd:ee:ff", "Hw": "TP-Link", "Date": "2025-09-06 00:58:26", "Known": 1, "Now": 1 } ]2.2GET /api/host/:id—— 按 ID 查询单台主机
GET /api/host/:id按主键id返回单台主机的 JSON。实现见 backend/internal/api/api-hosts.go:先通过getHostByID(见 backend/internal/api/functions.go)将路径参数转为 int 后调用gdb.SelectByID,随后用check.DNS(host)动态解析一次该主机的反向 DNS 并写入host.DNS字段,最后以缩进 JSON 返回。
请求示例:
curl http://0.0.0.0:8840/api/host/1若传入的id不存在,gdb.SelectByID使用First查询会返回零值Host(见 backend/internal/gdb/select.go),即各字段为空、ID为0的对象,调用方需要自行判断。
3. 主机编辑与删除接口
3.1GET /api/edit/:id/:name/*known—— 修改名称 / 切换 Known 状态
GET /api/edit/:id/:name/*known用于编辑主机:必填id(主机 ID)与name(新名称);known为可选路径参数,当取值为toggle时翻转该主机的 Known 状态。
对应实现见 backend/internal/api/api-hosts.go:
host.Name = name if toggleKnown == "/toggle" { host.Known = 1 - host.Known } gdb.Update("now", host)两点实现细节值得注意:
- 由于该路由在 Gin 中使用通配符
*known,实际捕获到的参数会带前导斜杠(/toggle),因此源码中比较的是字符串"/toggle"。若不传该段,c.Param("known")为空,仅执行改名。 Known字段是int,1 - Known实现了已知(1)与未知(0)之间的双向翻转。
前端封装apiEditHost(id, name, known)的调用方式见 frontend/src/functions/api.ts。
请求示例(改名为nas):
curl "http://0.0.0.0:8840/api/edit/3/nas/"请求示例(改名并切换 Known 状态):
curl "http://0.0.0.0:8840/api/edit/3/nas/toggle"成功返回"OK"。
3.2GET /api/host/del/:id—— 删除主机
GET /api/host/del/:id按id从当前主机表删除记录。实现见 backend/internal/api/api-hosts.go:先取回该主机对象(用于日志输出),再调用gdb.Delete("now", host.ID)从now表删除,成功返回"OK"。
请求示例:
curl http://0.0.0.0:8840/api/host/del/33.3GET /api/host/add/:mac—— 手动添加主机(路由已注册的补充接口)
官方 API 文档未单独列出该接口,但路由表中已注册(见 backend/internal/api/routes.go),在此一并说明。该接口以mac为必填路径参数,并通过 query 参数支持name、ip、hw(硬件厂商)三个可选字段,实现见 backend/internal/api/api-hosts.go:
- 若该 MAC 已存在于
now表,直接返回已有主机记录; - 否则用传入参数构造新的
models.Host写入数据库,并返回新记录。
请求示例:
curl "http://0.0.0.0:8840/api/host/add/11:22:33:44:55:66?name=printer&ip=192.168.1.50"4. 历史记录接口
历史数据存放在独立的history表中,由扫描例行程序持续写入(相关后台逻辑见 backend/internal/routines/scan-routine.go),并由 backend/internal/routines/trim-history.go 按配置定期裁剪。
4.1GET /api/history—— 全量历史(不推荐)
GET /api/history返回history表中的全部记录。实现见 backend/internal/api/api-history.go:直接执行gdb.Select("history")。官方文档明确警告:不推荐在生产环境调用该接口,输出数据量可能非常大。需要全量导出时建议改用数据库直查或按设备、按日期分批拉取。
4.2GET /api/history/:mac?num=N—— 按 MAC 取最近 N 条历史
GET /api/history/:mac?num=20返回指定mac的最近num条历史记录(按时间倒序)。实现见 backend/internal/api/api-history.go 与 backend/internal/gdb/select.go:
tab.Where("\"MAC\" = ?", mac). Order("\"DATE\" DESC"). Limit(number). Find(&hosts)即先按 MAC 过滤,再按日期倒序排列并LIMIT截断。num通过strconv.Atoi解析,若缺失或非法则解析为0(此时不会返回记录)。
请求示例:
curl "http://0.0.0.0:8840/api/history/aa:bb:cc:dd:ee:ff?num=20"值得一提的是,前端主机详情页正是通过该接口加载历史曲线,默认一次性拉取最近 210 条(见 frontend/src/functions/api.ts)。
4.3GET /api/history/:mac/:date—— 按 MAC 与日期过滤历史
GET /api/history/:mac/:date返回指定mac在date对应时间段内的历史记录。date格式非常灵活,官方文档说明"可以是2、2025-07、2025-07-26等任意前缀"。
其底层原理在 backend/internal/gdb/select.go 中一目了然——数据库层使用LIKE前缀匹配:
Where("\"MAC\" = ?", mac). Where("\"DATE\" LIKE ?", date+"%"). Find(&hosts)由于历史记录的DATE以YYYY-MM-DD HH:mm:ss完整时间戳存储,LIKE '2025-07%'会命中 2025 年 7 月的所有记录,LIKE '2%'则会命中所有以2开头的日期(包括年份 20xx 与日期的首位)。这也是"日期可以从2到2025-07再到2025-07-26随意截取"的原因。对应处理函数见 backend/internal/api/api-history.go,Swagger 注解中也列出了四种受支持格式:YYYY、YYYY-MM、YYYY-MM-DD、YYYY-MM-DD HH:mm:ss。
请求示例:
curl "http://0.0.0.0:8840/api/history/aa:bb:cc:dd:ee:ff/2025-07" curl "http://0.0.0.0:8840/api/history/aa:bb:cc:dd:ee:ff/2025-07-26"5. 网络探测接口
5.1GET /api/port/:addr/:port—— 单端口连通性探测
GET /api/port/:addr/:port探测指定地址addr(IP 或主机名)的某个 TCP 端口port是否开放,端口开放返回true,否则返回false。对应实现见 backend/internal/api/api-network.go 与 backend/internal/portscan/scan.go:
timeout := 3 * time.Second target := fmt.Sprintf("%s:%s", host, port) conn, err := net.DialTimeout("tcp", target, timeout) if err == nil { err = conn.Close() if err == nil { return true } } return false实现本质是一次带 3 秒超时的 TCP 拨号(net.DialTimeout):连接建立并成功关闭即视为端口开放;超时、拒绝连接或解析失败均视为关闭。这意味着它只能判断 TCP 端口,且一次探测最长耗时 3 秒。
官方文档给出的请求示例:
curl http://0.0.0.0:8840/api/port/192.168.2.2/8844响应为布尔值:true或false。
5.2GET /api/wol/:mac—— 发送 Wake-on-LAN 魔术包(路由已注册的补充接口)
GET /api/wol/:mac官方 API 文档未列出,但该接口已在路由表中注册(见 backend/internal/api/routes.go),用于按 MAC 地址发送 WOL 魔术包以远程唤醒设备。实现见 backend/internal/api/api-network.go:
packet, err := gowol.NewMagicPacket(mac) if !check.IfError(err) { err = packet.Send("255.255.255.255") slog.Info("Wake-on-LAN: " + mac) } c.IndentedJSON(http.StatusOK, !check.IfError(err))它使用gowol库构造魔术包并广播到255.255.255.255,响应为布尔值:发送成功返回true。前端在主机详情页通过apiWOL(mac)调用(见 frontend/src/functions/api.ts)。
请求示例:
curl http://0.0.0.0:8840/api/wol/aa:bb:cc:dd:ee:ff6. 系统与状态接口
6.1GET /api/status/*iface—— 主机统计状态
GET /api/status/*iface返回主机统计信息(总数、在线/离线、已知/未知)。iface为可选路径参数,仅统计指定网卡;不传或调用/api/status/则统计全部网卡。
响应结构由 backend/internal/models/models.go 的Stat定义:
| 字段 | 含义 |
|---|---|
Total | 主机总数 |
Online | 在线主机数 |
Offline | 离线主机数 |
Known | 已知主机数 |
Unknown | 未知主机数 |
实现逻辑见 backend/internal/api/api-system.go:
- 先取回全部当前主机
gdb.Select("now"); - 路径参数
iface是 Gin 通配符,捕获值带前导斜杠,因此源码先执行iface = iface[1:]去掉/; - 当
iface非空且不等于"undefined"时,仅保留host.Iface == iface的主机参与统计; - 遍历时以
Known > 0区分已知/未知,以Now > 0区分在线/离线。
请求示例:
curl http://0.0.0.0:8840/api/status/ curl http://0.0.0.0:8840/api/status/eth0示例响应:
{"Total": 12, "Online": 7, "Offline": 5, "Known": 9, "Unknown": 3}6.2GET /api/notify_test—— 发送测试通知
GET /api/notify_test发送一条测试通知,用于验证通知渠道配置是否生效。实现见 backend/internal/api/api-system.go 与 backend/internal/notify/shout.go:
msg := "test notification" slog.Info("Sending " + msg) shout(msg)shout函数通过 shoutrrr 库将消息推送到配置的ShoutURL(支持 Gotify、Telegram、Discord 等多种渠道),并自动附加主机名前缀WatchYourLAN on '<hostname>':(见 backend/internal/notify/shout.go)。若未配置ShoutURL,则静默跳过。调用成功返回 HTTP 200,且该接口同时会写日志,便于排查。
请求示例:
curl http://0.0.0.0:8840/api/notify_test6.3 其他系统接口:/api/version、/api/rescan、/api/config
这三个接口已在路由表中注册(见 backend/internal/api/routes.go),同样值得了解:
GET /api/version—— 返回当前运行版本字符串,来源为conf.AppConfig.Version(见 backend/internal/api/api-system.go),前端用它显示"关于"信息。GET /api/rescan—— 手动触发一次全接口重新扫描,内部调用routines.ScanRestart()(见 backend/internal/api/api-system.go),返回 HTTP 200,适合在扫描例行程序异常或新设备接入后手动拉取。GET /api/config—— 返回应用当前完整配置(models.Conf,字段覆盖监听地址、端口、主题、扫描参数、数据库连接、InfluxDB/Prometheus 配置等,定义见 backend/internal/models/models.go),前端配置页据此渲染表单。
7. 配置保存类 POST 接口
除了查询与操作类 GET 接口,backend/internal/api/routes.go 还注册了四个配置保存接口,均由表单(application/x-www-form-urlencoded)提交,保存成功后重定向回来源页面。参数解析逻辑集中在 backend/internal/api/config.go。
| 接口 | 提交的表单字段 | 说明 |
|---|---|---|
POST /api/config/ | host、port、theme、color、node、shout | 基础配置:监听地址、端口、主题、颜色、Node 路径、通知 URL |
POST /api/config_settings/ | log、arpargs、ifaces、usedb、pgconnect、timeout、trim、arpstrs[] | 扫描设置:日志级别、ARP 参数、网卡列表、数据库切换、扫描超时、历史裁剪天数、ARP 附加字符串 |
POST /api/config_influx/ | addr、token、org、bucket、enable、skip | InfluxDB 导出配置;enable/skip取"on"表示启用 |
POST /api/config_prometheus/ | enable | Prometheus 指标导出开关,"on"表示启用 |
几个值得注意的实现细节(均来自 backend/internal/api/config.go):
- 保存扫描设置时会比较
usedb与pgconnect是否变化,只有变化时才重新调用gdb.Connect()切换数据库(config.go); arpstrs通过c.PostFormArray("arpstrs")收集多值,并过滤掉空字符串;- 保存完成后会调用
routines.ScanRestart()让新扫描参数立即生效(config.go)。
8. 前端调用视角与集成建议
从 frontend/src/functions/api.ts 可以完整看到这些接口在前端页面中的实际使用场景:
apiGetAllHosts→/api/all(首页主机表格)apiGetHost→/api/host/:id(主机详情页)apiEditHost→/api/edit/:id/:name/:known(编辑主机)apiDelHost→/api/host/del/:id(删除主机)apiGetHistory→/api/history/:mac/?num=210(历史曲线)apiGetHistoryByDate→/api/history/:mac/:date(按日期筛选历史)apiPortScan→/api/port/:ip/:port(主机详情页端口探测)apiWOL→/api/wol/:mac(远程唤醒按钮)apiTestNotify→/api/notify_test(配置页测试通知)apiGetConfig、apiGetVersion→ 配置页与"关于"页面
若要将 WatchYourLAN 集成进自己的自动化脚本或第三方系统,建议遵循以下几点:
- 优先使用带
num限制或日期过滤的历史接口,避免调用/api/history全量接口造成不必要的网络与内存开销; /api/edit/、/api/host/del/、/api/rescan/会改变系统状态,调用时应明确其副作用并做好幂等处理;- 端口探测
/api/port/:addr/:port单次最长耗时 3 秒(见 backend/internal/portscan/scan.go),批量探测时应控制并发并设置合理的客户端超时; - 接口返回的
Known、Now均为int(1/0),与 JSON 布尔值不同,解析时注意类型转换; - 如需对外暴露 API,建议参考仓库中的 docker-compose-auth.yml 增加 Basic Auth 保护,避免未授权访问触发删除、编辑等操作。
9. 接口速查表
| 方法与路径 | 功能 | 关键参数 | 返回 |
|---|---|---|---|
GET /api/all | 全部主机 | — | Host[] |
GET /api/host/:id | 单台主机 | id | Host |
GET /api/edit/:id/:name/*known | 改名 / 切换 Known | known=toggle可选 | "OK" |
GET /api/host/del/:id | 删除主机 | id | "OK" |
GET /api/host/add/:mac | 手动添加主机 | ?name=&ip=&hw=可选 | Host |
GET /api/history | 全量历史(慎用) | — | Host[] |
GET /api/history/:mac?num=N | 最近 N 条历史 | num | Host[] |
GET /api/history/:mac/:date | 按日期前缀过滤历史 | date支持YYYY/YYYY-MM/YYYY-MM-DD/完整时间戳 | Host[] |
GET /api/port/:addr/:port | TCP 端口探测(3s 超时) | addr、port | true/false |
GET /api/wol/:mac | 发送 Wake-on-LAN | mac | true/false |
GET /api/status/*iface | 主机统计 | iface可选 | Stat |
GET /api/notify_test | 测试通知 | — | HTTP 200 |
GET /api/version | 版本号 | — | string |
GET /api/rescan | 手动重扫 | — | HTTP 200 |
GET /api/config | 当前配置 | — | Conf |
POST /api/config/等 4 个接口 | 保存配置 | 见第 7 节表单字段 | 302 重定向 |
至此,WatchYourLAN 的 HTTP API 已全部覆盖:从主机与历史的增删查改,到端口探测、远程唤醒、状态统计、通知测试与配置管理,配合源码级调用链分析,你可以放心地将这些接口接入自己的监控面板、告警系统或自动化运维脚本中。
【免费下载链接】WatchYourLANLightweight network IP scanner written in Go. With notifications, history, export to Grafana项目地址: https://gitcode.com/GitHub_Trending/wa/WatchYourLAN
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考