大数跨境
0
0

ClaudeCode开源一个SDK?

ClaudeCode开源一个SDK? 枭龙云技术团队
2025-12-11
2
你好,我是易安,今天这期讲的是软件研发中一个很重要的概念:sdk,并带着你从零到一完成开发,全程借助ClaudeCode。

本文将带你完整走一遍开源 Java SDK 的开发与发布流程,从项目架构设计到成功发布到 Maven Central,让全球开发者都能通过一行依赖引入你的 SDK。

一、基础概念:API vs SDK

在开始之前,先搞清楚两个经常被混淆的概念。

1.1 什么是 API?

API(Application Programming Interface,应用程序编程接口) 是一组定义好的规则和协议,用于不同软件系统之间的通信。

  
   
    
    
     
      数据库
      
     
    
   
    
    
     
      API 服务器
      
     
    
   
    
    
     
      你的应用
      
     
    
   
    
    
     
     
      
       
        数据库
       
      
     
    
   
    
    
     
     
      
       
        API 服务器
       
      
     
    
   
    
    
     
     
      
       
        你的应用
       
      
     
    
   
    
     
    
   
    
     
    
   
    
     
    
   
    
     
    
   
    
     
    
   
    
     
    
   
    
     
    
   
    HTTP 请求 (GET /users/123)
    
   
    查询用户数据
    
   
    返回用户数据
    
   
    JSON 响应 {"id": 123, "name": "张三"}
    
   
  

简单来说,API 就像餐厅的菜单

  • • 菜单告诉你有什么菜(端点)
  • • 每道菜需要什么配料(参数)
  • • 上菜的形式(响应格式)

1.2 什么是 SDK?

SDK(Software Development Kit,软件开发工具包) 是一套封装好的工具集,帮助开发者更方便地使用 API。

SDK 就像餐厅的外卖 App

  • • 你不需要记住菜单上的所有菜名
  • • 不需要自己打电话点餐
  • • 点几下按钮,饭就送到了

1.3 API vs SDK 对比

  
   
    
     
    
    
     
    
    
     
    
    
     
    
    
     
    
    
     
    
    
     
     
     
     
      
       
        
         
         
          
           

使用 SDK

调用方法

自动构建请求

自动解析响应

统一错误处理

内置重试机制

SDK

开发者

API

类型安全对象

异常体系

可靠性保障

直接调用 API

手写 HTTP 请求

手动解析 JSON

自己处理错误

自己实现重试

API

开发者

响应处理

异常处理

重试逻辑

对比项
直接调用 API
使用 SDK
代码量
多,需要手写大量样板代码
少,一行代码搞定
类型安全
无,运行时才发现错误
有,编译时就能检查
学习成本
高,需要阅读 API 文档
低,IDE 智能提示
维护成本
高,API 变更需要到处改
低,升级 SDK 版本即可

1.4 代码对比示例

直接调用 API:

// 需要手写大量代码
HttpClientclient= HttpClient.newHttpClient();
HttpRequestrequest= HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/users/123"))
    .header("Authorization""Bearer " + token)
    .header("Content-Type""application/json")
    .GET()
    .build();

HttpResponse<String> response = client.send(request,
    HttpResponse.BodyHandlers.ofString());

// 手动解析 JSON
Gsongson=newGson();
Useruser= gson.fromJson(response.body(), User.class);

使用 SDK:

// 一行代码搞定
User user = client.users().get(123);

二、为什么要开发 SDK?

当你频繁调用某个第三方 API 时,每次都要手写 HTTP 请求、处理响应、解析 JSON... 这些重复劳动不仅耗时,还容易出错。

SDK(Software Development Kit) 就是为了解决这个问题而生的:

  • • 封装复杂性:将 HTTP 请求、签名、重试等逻辑封装起来
  • • 类型安全:提供强类型的请求/响应对象,编译时就能发现错误
  • • 开发体验:IDE 智能提示,降低使用门槛
  • • 统一维护:API 变更时只需更新 SDK,下游用户升级版本即可

三、设计模式详解

在编写 SDK 之前,需要了解两个核心设计模式。

3.1 Builder 模式(建造者模式)

问题场景:当一个对象有很多可选参数时,构造函数会变得很复杂。

  
   
    
     
    
    
     
    
    
     
    
    
     
    
    
     
    
    
     
    
    
     
     
     
     
      
       
        
         
         
          
           

传统构造函数的问题

new Client(token, 10000, 3, true, 'https://api.com', null, null)

参数太多,容易搞错顺序

可选参数难以处理

代码可读性差

Builder 模式解决方案

代码示例

// Builder 模式 - 链式调用,清晰易读
Client client = new ClientBuilder()
    .token("your-token")      // 必需参数
    .timeout(10000)           // 可选,有默认值
    .retryCount(3)            // 可选,有默认值
    .baseUrl("https://...")   // 可选,有默认值
    .build();

Builder 模式的优点

  1. 1. 可读性强:每个参数都有名字,一目了然
  2. 2. 灵活性高:可选参数可以省略,使用默认值
  3. 3. 不可变性:build() 后返回不可变对象
  4. 4. 参数校验:可以在 build() 时统一校验

3.2 门面模式(Facade Pattern)

问题场景:系统内部有很多复杂的子系统,直接暴露给用户会让人崩溃。

门面模式解决方案


代码示例

// 用户只需要和 Client 这一个"门面"打交道
Client client = new ClientBuilder().token("xxx").build();

// 所有复杂性都被隐藏了
List<Group> groups = client.groups().list();
Topic topic = client.topics().get(topicId);
User me = client.users().getMe();

门面模式的优点

  1. 1. 简化接口:用户只需要了解一个入口
  2. 2. 解耦:用户代码和内部实现解耦
  3. 3. 易于使用:降低学习成本
  4. 4. 灵活重构:内部实现可以随意修改,不影响用户

四、SDK 架构设计

一个优秀的 SDK 需要清晰的架构设计,以我这两天做的知识星球 SDK 为例,以下是推荐的分层架构:


4.1 核心组件说明

组件
职责
示例
Client
SDK 门面类,聚合所有 Request 模块
client.groups().list()
ClientBuilder
Builder 模式构建客户端
配置 token、超时、重试等
Request 模块
各功能域的 API 封装
GroupsRequest、TopicsRequest
HttpClient
底层 HTTP 客户端
请求发送、重试、签名
Models
数据模型
Group、Topic、User
Exceptions
异常体系
按错误码分类的异常

4.2 异常设计

良好的异常设计能让用户快速定位问题:

五、项目结构

推荐使用 Monorepo 管理多语言 SDK:

my-sdk/
├── spec/                    # API 规范 (SSOT)
│   ├── openapi.yaml         # OpenAPI 规范
│   ├── errors/              # 错误码定义
│   └── sdk-design/          # SDK 设计规范
├── packages/
│   ├── java/                # Java SDK
│   │   ├── pom.xml
│   │   └── src/
│   │       ├── main/java/com/example/sdk/
│   │       │   ├── Client.java
│   │       │   ├── ClientBuilder.java
│   │       │   ├── http/
│   │       │   │   └── HttpClient.java
│   │       │   ├── request/
│   │       │   │   ├── GroupsRequest.java
│   │       │   │   ├── TopicsRequest.java
│   │       │   │   └── UsersRequest.java
│   │       │   ├── model/
│   │       │   │   ├── Group.java
│   │       │   │   ├── Topic.java
│   │       │   │   └── User.java
│   │       │   └── exception/
│   │       │       ├── BaseException.java
│   │       │       └── AuthException.java
│   │       └── test/
│   ├── typescript/          # TypeScript SDK
│   ├── go/                  # Go SDK
│   └── python/              # Python SDK
└── docs/                    # 文档

六、核心代码实现

6.1 Builder 模式构建客户端

public classClientBuilder {
    private String token;
    privateinttimeout=10000;
    privateintretryCount=3;

    public ClientBuilder token(String token) {
        this.token = token;
        returnthis;
    }

    public ClientBuilder timeout(int timeout) {
        this.timeout = timeout;
        returnthis;
    }

    public Client build() {
        if (token == null || token.isEmpty()) {
            thrownewIllegalArgumentException("Token is required");
        }
        returnnewClient(this);
    }
}

6.2 门面类设计

public classClient {
    privatefinal GroupsRequest groups;
    privatefinal TopicsRequest topics;
    privatefinal UsersRequest users;

    Client(ClientBuilder builder) {
        HttpClienthttpClient=newHttpClient(builder);
        this.groups = newGroupsRequest(httpClient);
        this.topics = newTopicsRequest(httpClient);
        this.users = newUsersRequest(httpClient);
    }

    public GroupsRequest groups() { return groups; }
    public TopicsRequest topics() { return topics; }
    public UsersRequest users() { return users; }
}

6.3 使用示例

// 创建客户端
Clientclient=newClientBuilder()
    .token("your-token")
    .timeout(10000)
    .build();

// 获取列表
List<Group> groups = client.groups().list();

// 获取详情
Topictopic= client.topics().get(topicId);

// 获取当前用户
Userme= client.users().getMe();

七、发布到 Maven Central

这是本文的重点!让我们一步步完成发布流程。

7.1 发布流程总览

7.2 配置 pom.xml

Maven Central 对 pom.xml 有严格要求,必须包含以下信息:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/xsd/maven-4.0.0.xsd"
>

    <modelVersion>4.0.0</modelVersion>

    <!-- 基本信息 -->
    <groupId>io.github.your-username</groupId>
    <artifactId>your-sdk</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <!-- 项目描述(必需) -->
    <name>your-sdk</name>
    <description>Your SDK Description</description>
    <url>https://github.com/your-username/your-sdk</url>

    <!-- 开源许可证(必需) -->
    <licenses>
        <license>
            <name>MIT License</name>
            <url>https://opensource.org/licenses/MIT</url>
        </license>
    </licenses>

    <!-- 开发者信息(必需) -->
    <developers>
        <developer>
            <name>Your Name</name>
            <email>your-email@example.com</email>
        </developer>
    </developers>

    <!-- 源码管理(必需) -->
    <scm>
        <connection>scm:git:git://github.com/your-username/your-sdk.git</connection>
        <developerConnection>scm:git:ssh://github.com:your-username/your-sdk.git</developerConnection>
        <url>https://github.com/your-username/your-sdk/tree/main</url>
    </scm>

    <!-- 构建插件 -->
    <build>
        <plugins>
            <!-- 源码包 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- Javadoc -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>3.6.3</version>
                <executions>
                    <execution>
                        <id>attach-javadocs</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- GPG 签名(必需) -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-gpg-plugin</artifactId>
                <version>3.2.4</version>
                <executions>
                    <execution>
                        <id>sign-artifacts</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>sign</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- Central Publishing 插件 -->
            <plugin>
                <groupId>org.sonatype.central</groupId>
                <artifactId>central-publishing-maven-plugin</artifactId>
                <version>0.6.0</version>
                <extensions>true</extensions>
                <configuration>
                    <publishingServerId>central</publishingServerId>
                    <autoPublish>true</autoPublish>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

7.3 GroupId 选择

GroupId 有两种选择:

类型
示例
验证方式
域名反转 com.example
需要证明你拥有 example.com 域名
GitHub 账号 io.github.username
在 GitHub 创建验证仓库(推荐)

**推荐使用 io.github.username**,无需域名验证,只需在 GitHub 创建一个特定名称的空仓库即可。

7.4 注册 Maven Central 账号

  1. 1. 访问 https://central.sonatype.com/
  2. 2. 使用 GitHub 账号登录
  3. 3. 进入 Namespaces 页面
  4. 4. 点击 Add Namespace
  5. 5. 输入 io.github.your-username(替换为你的用户名)
  6. 6. 按提示在 GitHub 创建验证仓库
  
   
    
    
     
      GitHub
      
     
    
   
    
    
     
      Sonatype Central
      
     
    
   
    
    
     
      用户
      
     
    
   
    
    
     
     
      
       
        GitHub
       
      
     
    
   
    
    
     
     
      
       
        Sonatype Central
       
      
     
    
   
    
    
     
     
      
       
        用户
       
      
     
    
   
    
     
    
   
    
     
    
   
    
     
    
   
    
     
    
   
    
     
    
   
    
     
    
   
    
     
    
   
    1. 登录 Central
    
   
    2. 显示 Namespaces 页面
    
   
    3. 添加 io.github.username
    
   
    4. 返回验证仓库名称
    
   
    5. 创建验证仓库
    
   
    6. 自动验证
    
   
    7. 命名空间验证成功
    
   
  

7.5 生成 GPG 密钥

Maven Central 要求所有发布的 artifacts 必须经过 GPG 签名。

安装 GPG(macOS)

brew install gnupg

生成密钥

gpg --full-generate-key

按提示输入:

  • • 密钥类型:RSA and RSA(默认)
  • • 密钥长度:4096
  • • 有效期:根据需要选择
  • • 真实姓名:你的名字
  • • 邮箱:你的邮箱
  • • 密码短语:设置一个强密码(务必记住!

查看密钥 ID

gpg --list-keys --keyid-format LONG

输出示例:

pub   rsa4096/XXXXXXXXXXXXXXXX 2025-12-10 [SC]
      YYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXX
uid                   [ 绝对 ] Your Name <your-email@example.com>
sub   rsa4096/ZZZZZZZZZZZZZZZZ 2025-12-10 [E]

其中 XXXXXXXXXXXXXXXX 就是你的 Key ID。

上传公钥到密钥服务器

gpg --keyserver keyserver.ubuntu.com --send-keys YOUR_KEY_ID

7.6 生成 Central Portal Token

  1. 1. 登录 https://central.sonatype.com/

  2. 2. 点击右上角头像 → View Account

  3. 3. 点击 Generate User Token

  4. 4. 复制 username 和 password

7.7 配置 settings.xml

在 ~/.m2/settings.xml 中添加:

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0
                              https://maven.apache.org/xsd/settings-1.2.0.xsd"
>

    <servers>
        <server>
            <id>central</id>
            <username>你的Token用户名</username>
            <password>你的Token密码</password>
        </server>
    </servers>
</settings>

7.8 执行发布

cd packages/java
mvn clean deploy

发布过程中 GPG 会提示输入密码短语,输入后等待上传完成。

7.9 验证发布结果

  1. 1. 访问 https://central.sonatype.com/ 查看发布状态

  2. 2. 同步到 Maven Central 搜索索引需要 10-30 分钟
  3. 3. 完全同步可能需要 几小时

八、常见问题

Q1: GPG 签名失败 "Inappropriate ioctl for device"

这是因为 GPG 无法在非交互式终端中请求密码。解决方案:

# 配置 GPG 使用 loopback 模式
mkdir -p ~/.gnupg
echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf
echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent

Q2: 编译失败 "symbol not found"

通常是 Lombok 版本与 Java 版本不兼容:

  • • Java 21 需要 Lombok 1.18.30+
  • • 不要使用 SNAPSHOT 版本发布到 Central

Q3: 发布后在 Maven Central 搜不到

新发布的 artifacts 需要时间同步:

  • • 直接通过坐标引用:约 10-30 分钟
  • • 在 search.maven.org 搜索:可能需要几小时

九、发布后的使用

发布成功后,用户可以这样引入你的 SDK:

Maven

<dependency>
    <groupId>io.github.your-username</groupId>
    <artifactId>your-sdk</artifactId>
    <version>1.0.0</version>
</dependency>

Gradle

implementation 'io.github.your-username:your-sdk:1.0.0'

Gradle (Kotlin DSL)

implementation("io.github.your-username:your-sdk:1.0.0")

十、总结

看完以上的案例,你就能知道,发布一个开源 SDK 到 Maven Central 的完整流程包含这几个阶段:

关键要点

  1. 1. 理解概念:API 是接口规范,SDK 是封装好的工具包
  2. 2. 设计模式:Builder 模式构建对象,门面模式简化接口
  3. 3. 架构设计:清晰的分层,职责分明
  4. 4. pom.xml 配置:必须包含 name、description、url、licenses、developers、scm
  5. 5. GPG 签名:必需,用于验证 artifacts 完整性
  6. 6. groupId 选择:推荐使用 io.github.username,验证简单

希望这篇文章能帮助你成功发布自己的开源 SDK!如果有任何问题,欢迎在评论区交流。


相关链接:

  • • Maven Central Portal
  • • Central Publishing 插件文档
  • • GPG 密钥管理
  • 我是易安,一位专注AI技术研究的AI超级个体。每天为大家带来前沿AI工具评测和实践经验,用通俗易懂的方式解读复杂的技术概念,👇长按扫码关注,一起探索AI技术的无限可能!

  • 如果觉得我的文章对你有帮助的话,可以帮我点个赞👍或者喜欢❤,让更多跟你一样好品味的人看到这些内容,感谢🙏


  • 推荐阅读

    来,这是易安的介绍(第2版,交个朋友,限时送福利)
    我和深圳大冲的故事

【声明】内容源于网络
0
0
枭龙云技术团队
枭龙云技术团队
内容 233
粉丝 0
枭龙云技术团队 枭龙云技术团队
总阅读17
粉丝0
内容233