首页
/ freeCodeCamp「Request Header Parser Microservice」:一个从 HTTP 请求头读取信息的后端微服务项目实战

freeCodeCamp「Request Header Parser Microservice」:一个从 HTTP 请求头读取信息的后端微服务项目实战

2026-09-06 15:00:00作者:彭桢灵Jeremy

本文为 freeCodeCamp 课程中「Back-End Development and APIs」认证的第 2 个项目——Request Header Parser Microservice(请求头解析微服务)。你将构建一个功能上与 freeCodeCamp 官方示例应用等价的 JavaScript 全栈应用,核心任务是通过一个 /api/whoami 接口从 HTTP 请求头中解析出访问者的 IP 地址、首选语言和所用软件,并以 JSON 形式返回。读完本文,你会掌握该项目的完整接口契约、测试断言的逐条解读,以及这类后端项目型课程题在 freeCodeCamp 课程体系中的组织方式与提交机制。

项目定位:Back-End Development and APIs 认证的第二个项目

该项目是「Back-End Development and APIs」认证下 5 个项目中的第 2 个。课程的区块结构定义在 back-end-development-and-apis-projects.json 中,challengeOrder 数组明确了项目顺序:

  1. Timestamp Microservice(bd7158d8c443edefaeb5bdef
  2. Request Header Parser Microservice(bd7158d8c443edefaeb5bdff
  3. URL Shortener Microservice(bd7158d8c443edefaeb5bd0e
  4. Exercise Tracker(5a8b073d06fa14fcfde687aa
  5. File Metadata Microservice(bd7158d8c443edefaeb5bd0f

课程文件本身是 back-end-development-and-apis-projects/bd7158d8c443edefaeb5bdff.md。其 frontmatter 中的关键字段值得逐一说明:

  • id: bd7158d8c443edefaeb5bdff——挑战的唯一标识,也是目录中同名 .md 文件的文件名,freeCodeCamp 的课程体系以该 id 关联挑战文件、结构文件与前端组件;
  • title: Request Header Parser Microservice——展示标题;
  • challengeType: 4——挑战类型。在 challenge-types.ts 中,4 对应 backEndProject(后端项目型挑战);
  • dashedName: request-header-parser-microservice——由标题派生的 URL 短横线命名,构成访问路径 /learn/back-end-development-and-apis/back-end-development-and-apis-projects/request-header-parser-microservice 的最后一段。该路径前缀在 cert-and-project-map.ts 中的 apiMicroBase 常量定义;e2e 测试 hotkeys.spec.ts 中同样硬编码了这条完整学习路径,可视为路径格式的可执行验证。

挑战类型 4 意味着什么:提交方式由 challengeType 决定

从源码结构看,challengeType 不只是一个分类标签,它同时决定了前端如何渲染这个挑战页面、以及完成后如何提交答案:

  • 视图类型challenge-types.tsviewTypesbackEndProject 映射为 'backend' 视图,即以项目说明页面呈现,而非代码编辑器页面;
  • 提交类型submitTypesbackEndProject 映射为 'project.backEnd',源码注释明确写道:
// requires two urls
// a hosted URL where the app is running live
// project code url like GitHub
[backEndProject]: 'project.backEnd',

也就是说,完成本项目的提交需要两个 URL:一个是应用在线运行的地址(课程测试将直接请求它),另一个是代码仓库地址。这正是该挑战在课程描述中要求"克隆模板仓库本地完成,或自选站点构建器部署"的底层原因——测试系统只对部署后的公开地址发起请求,不检查本地代码。此外,hasNoSolution 函数(challenge-types.ts)将 backEndProject 列入"无标准答案"清单,即课程不提供可直接运行的参考实现,需自行搭建。

在证书层面,cert-and-project-map.ts 将本项目登记在 Back-End Development and APIs 认证下(certSlug: Certification.BackEndDevApis),其 link 指向 ${apiMicroBase}/request-header-parser-microservice,与上述学习路径一致。

核心任务:构建 /api/whoami 接口

课程描述给出的功能目标是:构建一个与 freeCodeCamp 官方示例服务功能相似的 JavaScript 全栈应用。两种完成途径为:

  1. 克隆官方 boilerplate 仓库(boilerplate-project-headerparser)并在本地完成项目;
  2. 使用任意的站点构建器完成项目,但必须包含 boilerplate 仓库中的所有文件。

接口契约:三个必须返回的键

课程内嵌的自动化测试(以 fetch 请求部署地址)定义了精确的接口契约。请求 GET /api/whoami 必须返回一个 JSON 对象,且包含以下三个键,每个值都必须非空

返回键 数据来源(HTTP 请求头) 测试断言
ipaddress X-Forwarded-For(经反向代理/CDN 时首选) assert(data.ipaddress && data.ipaddress.length > 0)
language Accept-Language assert(data.language && data.language.length > 0)
software User-Agent assert(data.software && data.software.length > 0)

三条测试的逻辑完全同构,以下以 IP 地址一条为例,测试代码直接取自课程文件 bd7158d8c443edefaeb5bdff.md

const response = await fetch(code + '/api/whoami');
if (!response.ok) {
  throw new Error(await response.text());
}
const data = await response.json();
assert(data.ipaddress && data.ipaddress.length > 0);

其中 code 变量即你在提交时填写的应用托管 URL。可以从测试代码中提炼出几条硬性要求:

  • 接口必须返回 2xx 状态码,否则 response.ok 为 false 直接抛错;
  • 响应体必须是可被 response.json() 解析的合法 JSON,这隐含要求设置 Content-Type: application/json(Express 中用 res.json() 即可满足);
  • 三个键的值必须存在且 length > 0——注意是 length 判断,意味着空字符串也会判负。

请求头解析的实现要点

按 HTTP 规范,三个键应分别读取如下请求头,这正是本项目考察的核心知识点:

  • IP 地址:客户端真实 IP 通常在 X-Forwarded-For 头中(应用置于反向代理之后时);X-Forwarded-For 是逗号分隔的代理链,第一个值才是发起客户端的 IP;无该头时可退回连接层的 req.ip
  • 首选语言:读取 Accept-Language 头。注意该头可能是带质量系数的列表(如 en-US,en;q=0.9,zh-CN;q=0.8),测试只要求非空,因此返回原值或其首段均可通过。
  • 所用软件:读取 User-Agent 头,通常形如浏览器名称加版本信息,直接返回原值即可。

一个满足契约的最小 Express 实现骨架如下(供理解测试如何跑通,而非完整参考答案):

app.get('/api/whoami', (req, res) => {
  const ip = (req.headers['x-forwarded-for'] || req.ip).split(',')[0].trim();
  res.json({
    ipaddress: ip,
    language: req.headers['accept-language'],
    software: req.headers['user-agent']
  });
});

实现时值得注意的边界情况:X-Forwarded-For 可能缺失(直连部署时为空),需有回退逻辑;Accept-Language 理论上也可能缺失,但真实浏览器几乎总会携带。由于测试只断言"非空",这类细节决定你的接口在异常请求下是否健壮。

防作弊断言:必须提交自己的项目

测试文件的第一条断言(bd7158d8c443edefaeb5bdff.md)是防作弊检查:

assert(
  !/.*\/request-header-parser-microservice\.freecodecamp\.rocks/.test(
    code
  )
);

课程描述中给出的官方示例地址属于 *.freecodecamp.rocks 域名。这条断言确保你提交的托管 URL 不是官方示例服务本身——正则对 code(你填写的 URL)做子串匹配,只要 URL 中出现示例服务路径就判负。课程描述也明确提示:"You should provide your own project, not the example URL."

从仓库代码看该项目的可验证链路

本课程题在仓库中的关联路径形成了完整的可验证链路,可供读者自行深入核对:

小结

Request Header Parser Microservice 是 freeCodeCamp 后端认证中体量最小但契约最精确的项目:一个 GET /api/whoami 接口,从 X-Forwarded-ForAccept-LanguageUser-Agent 三个请求头取值,以 JSON 返回 ipaddresslanguagesoftware 三个非空键,配合 2xx 状态码即通过全部功能断言。完成它需要掌握 Express 路由、请求头读取与 JSON 响应,并完成一次真实的公网部署——这也是该课程用"提交托管 URL 供服务器主动探测"这种设计,把 HTTP 协议知识落到实战的意图所在。

登录后查看全文
热门项目推荐
相关项目推荐