# 钩子概览

本章将介绍，如何使用飞布的钩子机制扩展API，实现自定义逻辑。

> 在编程中，钩子（hooks）是一种机制，允许您在程序执行特定操作时插入代码，以更改或扩展程序的行为。钩子通常用于在不修改程序源代码的情况下对程序进行自定义，或对程序进行调试或监控。

飞布提供了各种类型的钩子，包括API请求生命周期的钩子、授权生命周期的钩子、文件上传生命周期的钩子，用于扩展逻辑。

钩子本质上是http请求生命周期的“切面”​，在请求经过“切面”时，通过自定义函数，修改请求的输入参数和响应结果。

飞布服务与钩子服务相互独立，服务间通过HTTP协议通讯，可分别部署。钩子服务本质上是一个实现了飞布钩子规范的WEB服务。因此，可以用任意后端开发语言实现钩子，真正做到多语言兼容。

<figure><img src="/files/8fq02fIJpHna2QwpWABB" alt=""><figcaption><p>飞布服务与钩子服务调用关系</p></figcaption></figure>

不仅，飞布可以调用钩子，钩子也可以调用飞布。此时，飞布相对于钩子是一个数据代理服务，同时飞布的所有OPERATION都可以供钩子使用。在另一个角度上，钩子也可以认为是serverless架构。

## 安装钩子

接着，我们学习如何安装钩子。

在状态栏中有一项叫做“<mark style="color:red;">钩子模板</mark>”，默认为空。点击后，可打开模板页，默认为空。点击右上角“浏览模板市场”，打开模板下载页，里面展示了两种类型的模板：

* 钩子模板，用于生成钩子服务的脚手架
* 客户端模板，用于生成客户端的SDK，详情见 [客户端SDK](/v1.0/shi-yong-bu-shu-shang-xian/sdk-sheng-cheng.md)

今天我们只介绍钩子模板。我们以golang钩子模板为例。

<figure><img src="/files/7gloIA98WQRhU1Ats90u" alt=""><figcaption></figcaption></figure>

1，在模板下载页，选择 `golang-server` ，点击下载

1.1 Fireboom将从下述仓库中下载模板：

* V1.0版本：<https://github.com/fireboomio/sdk-template\\_go-server>
* V2.0版本：<https://github.com/fireboomio/sdk-template\\_go-server/tree/test>

不同Fireboom版本，下载模板的分支不同！

1.2 下载后，将在 `template` 目录下增加 `golang_server` 目录，包含有4部分：

* README.md：自述文件
* manifest.json：清单配置，存储了该模板的基本信息，和界面一一对应

  ```json
  {
    "name": "go-server",
    "author": "fireboom",
    "version": "0.1.0",
    "description": "这里是sdk的描述",
    "outputPath": "./custom-go",// 控制目标文件的生成路径，相对Fireboom根目录
    "enabled": false // 默认是关闭的
  }
  ```
* <mark style="color:red;">files：模板文件</mark>
  * .hbs：[handlerbars](https://www.handlebarsjs.cn/)格式，每次编译后替换目标文件
  * 其他文件，例如`.go`、`.html`，目标文件不存在时，生成（否则不生成）
* partials（可选）：每个文件都是一个模板片段，主要用于复用逻辑，可被files的hbs中引用

{% tabs %}
{% tab title="golang" %}

```
template
├─ golang-server
│  ├─ README.md
│  ├─ files
│  │  ├─ generated
│  │  │  └─ models.go.hbs
│  │  ├─ go.mod
│  │  ├─ helix.html
│  │  ├─ main.go
│  │  ├─ pkg
│  │  │  ├─ base
│  │  │  │  ├─ client.go
│  │  │  │  ├─ operation.go
│  │  │  │  ├─ request.go
│  │  │  │  ├─ upload.go
│  │  │  │  └─ user.go
│  │  │  ├─ consts
│  │  │  │  └─ env.go
│  │  │  ├─ plugins
│  │  │  │  ├─ graphqls.go
│  │  │  │  └─ internal_request.go
│  │  │  ├─ types
│  │  │  │  ├─ configure.go
│  │  │  │  └─ server.go
│  │  │  ├─ utils
│  │  │  │  ├─ config.go
│  │  │  │  ├─ file.go
│  │  │  │  ├─ http.go
│  │  │  │  ├─ random.go
│  │  │  │  └─ strings.go
│  │  │  └─ wgpb
│  │  │     └─ wundernode_config.pb.go
│  │  ├─ scripts
│  │  │  ├─ install.sh
│  │  │  ├─ run-build.sh
│  │  │  ├─ run-dev.sh
│  │  │  └─ run-prod.sh
│  │  └─ server
│  │     ├─ fireboom_server.go.hbs # 入口文件模板
│  │     └─ start.go
│  └─ manifest.json
```

{% endtab %}

{% tab title="nodejs" %}

```
template
├─ node-server
│  ├─ README.md
│  ├─ files
│  │  ├─ ecosystem.config.js
│  │  ├─ fireboom.server.ts.hbs
│  │  ├─ generated
│  │  │  ├─ claims.ts.hbs
│  │  │  ├─ client.legacy.ts.hbs
│  │  │  ├─ client.ts.hbs
│  │  │  ├─ fireboom.factory.ts
│  │  │  ├─ fireboom.internal.client.ts.hbs
│  │  │  ├─ fireboom.internal.operations.client.ts.hbs
│  │  │  ├─ fireboom.operations.ts.hbs
│  │  │  ├─ fireboom.server.ts.hbs
│  │  │  ├─ linkbuilder.ts.hbs
│  │  │  ├─ models.ts.hbs
│  │  │  ├─ prisma.ts.hbs
│  │  │  └─ testing.ts.hbs
│  │  ├─ nodemon.json
│  │  ├─ operations.tsconfig.json
│  │  ├─ package.json
│  │  ├─ scripts
│  │  │  ├─ buildOperations.ts
│  │  │  ├─ install.sh
│  │  │  ├─ run-build.sh
│  │  │  ├─ run-dev.sh
│  │  │  └─ run-prod.sh
│  │  └─ tsconfig.json
│  ├─ manifest.json
│  └─ partials
│     ├─ operation_partial.hbs
│     └─ schema_partial.hbs
```

{% endtab %}
{% endtabs %}

2，在模板页修改“生成路径”，并开启钩子开关（钩子模板同时只能开启1个）

3，后续每次触发“编译”，都会重新生成钩子文件（<mark style="color:orange;">非</mark><mark style="color:orange;">`.hbs`</mark><mark style="color:orange;">文件，只生成1次</mark>）

{% tabs %}
{% tab title="golang" %}

```
├─ custom-go
│  ├─ go.mod
│  ├─ go.sum
│  ├─ helix.html
│  ├─ main.go
│  ├─ pkg
│  │  ├─ base
│  │  │  ├─ client.go
│  │  │  ├─ operation.go
│  │  │  ├─ request.go
│  │  │  ├─ upload.go
│  │  │  └─ user.go
│  │  ├─ consts
│  │  │  └─ env.go
│  │  ├─ plugins
│  │  │  ├─ auth_hooks.go
│  │  │  ├─ global_hooks.go
│  │  │  ├─ graphqls.go
│  │  │  ├─ internal_request.go
│  │  │  ├─ operation_hooks.go
│  │  │  ├─ proxy_hooks.go
│  │  │  └─ upload_hooks.go
│  │  ├─ types
│  │  │  ├─ configure.go
│  │  │  └─ server.go
│  │  ├─ utils
│  │  │  ├─ config.go
│  │  │  ├─ file.go
│  │  │  ├─ http.go
│  │  │  ├─ random.go
│  │  │  └─ strings.go
│  │  └─ wgpb
│  │     └─ wundernode_config.pb.go
│  ├─ scripts
│  │  ├─ install.sh
│  │  ├─ run-build.sh
│  │  ├─ run-dev.sh
│  │  └─ run-prod.sh
│  ├─ server
│  │  └─ start.go
│  │  └─ fireboom_server.go # 生成的入口文件（重要！！！）
```

{% endtab %}

{% tab title="nodejs" %}

```
todo
```

{% endtab %}
{% endtabs %}

4，按照各语言的方法安装依赖，并启动钩子服务即可

钩子服务本质上是web服务，该服务会按照钩子规范注册对应路由，我们只需要在路由的控制器中完善业务逻辑即可，详情见 [启动钩子](/v1.0/jin-jie-gou-zi-ji-zhi/qi-dong-gou-zi.md)

## 升级钩子

接着，基于上述原理 ，学习如何升级模板。

1，在模板页选择 `golang-server` ，点击“...”，选择“升级”

Fireboom将重新从对应仓库下载模板，并覆盖旧模板

2，前往钩子生成目录，手工删除钩子模板目录下files目录中后缀不是`.hbs`的文件

```
├─ custom-go
│  ├─ go.mod
│  ├─ go.sum
│  ├─ helix.html
│  ├─ main.go
│  ├─ pkg //通常情况下，删除目标目录下的该文件就成，因为升级一般都是修改该目录
│  ├─ server
│  │  └─ start.go
```

3，重装依赖，启动钩子服务


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.fireboom.io/v1.0/jin-jie-gou-zi-ji-zhi/gou-zi-ji-zhi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
