【开源】APIJSON 框架

简述

APIJSON是一个关于API和JSON的综合技术或框架,一种专为API设计的JSON网络传输协议,以及基于这套协议实现的ORM库。

1. 定义与特点:

  • APIJSON是一种基于接口的JSON传输结构协议,它允许客户端定义任何JSON结构来向服务端发起请求,服务端则返回对应结构的JSON字符串,实现"所求即所得"的效果。
  • 它为简单的增删改查提供了完全自动化的万能API,能够零代码实时满足各种新增和变更需求。
  • 通过APIJSON,可以大幅降低开发和沟通成本,简化开发流程,缩短开发周期。

2. 主要作用:

  • APIJSON的主要作用在于简化客户端和服务端之间的数据交换过程,使得前后端开发者能够更加高效地协同工作。
  • 它支持多种编程语言和平台,包括JavaScript、Python、Java、C#等,因此具有广泛的应用价值。

3. 使用场景:

  • APIJSON特别适用于中小公司、团队及个人开发者,解决他们在客户端和服务端之间数据交换的问题。
  • 它被广泛应用于Web开发、移动应用开发、桌面应用开发等领域。

4. 基本用法:

  • 定义API接口:使用类似JSON的格式来定义API接口,包括URL、请求方法、参数、返回结果等信息。
  • 发送请求:使用HTTP客户端工具(如Postman)或编程语言中的HTTP请求库来发送请求。
  • 解析返回结果:APIJSON服务端会返回符合定义的JSON格式的数据作为响应,开发者可以解析和处理返回的数据。

5. 优势:

  • 结构清晰:APIJSON的层次结构简洁清晰,易于人阅读和编写,同时也易于机器解析和生成。
  • 高效性:相比XML,JSON更小、更快,更易解析,因此其被广泛应用于网络数据传输领域。
  • 通用性:支持多种编程语言和平台,使得APIJSON成为一种通用的数据交换格式。

APIJSON CRUD

1. 创建(Create)

  • **功能:**通过APIJSON,你可以轻松地向数据库中添加新的记录。
  • 实现:
    1. 定义API接口,指定请求方法(如POST)、URL和请求体(JSON格式)。
    2. 在请求体中,包含要创建的数据的字段和值。
    3. 发送请求,APIJSON后端服务将解析请求体,并将数据插入到数据库中。
  • **示例:**假设有一个名为users的表,并希望添加一个新用户。可以发送一个POST请求到/api/users,请求体如下:
java 复制代码
{  
  "user": {  
    "id": 0,  // 通常为自增主键,可省略或设为0  
    "name": "John Doe",  
    "age": 30,  
    "email": "johndoe@example.com"  
  }  
}

2. 读取(Read)

  • **功能:**通过APIJSON,你可以从数据库中检索数据。
  • 实现:
    1. 定义API接口,指定请求方法(如GET)、URL和查询参数(可选)。
    2. 发送请求,APIJSON后端服务将根据查询参数从数据库中检索数据。
  • **示例:**要检索所有用户,你可以发送一个GET请求到/api/users。要检索特定用户(如ID为1的用户),你可以发送GET请求到/api/users/1。
bash 复制代码
GET /User/1

返回结果:

json 复制代码
{  
  "code": 200,  
  "msg": "success",  
  "data": {  
    "User": {  
      "id": 1,  
      "name": "John Doe",  
      "age": 30  
    }  
  }  
}

3. 更新(Update)

  • **功能:**通过APIJSON,你可以修改数据库中的现有记录。
  • 实现:
    1. 定义API接口,指定请求方法(如PUT或PATCH)、URL和请求体(JSON格式)。
    2. 在请求体中,包含要更新的数据的字段和新的值,以及用于标识要更新的记录的ID或其他唯一标识符。
    3. 发送请求,APIJSON后端服务将解析请求体,并更新数据库中的记录。
      -**示例:**要更新ID为1的用户的邮箱地址,你可以发送一个PUT或PATCH请求到/api/users/1,请求体如下:
java 复制代码
{  
  "user": {  
    "id": 1,  
    "email": "newemail@example.com"  
  }  
}

4. 删除(Delete)

  • 功能: 通过APIJSON,你可以从数据库中删除现有记录。
  • 实现:
    1. 定义API接口,指定请求方法(如DELETE)、URL和查询参数(可选)。
    2. 发送请求,APIJSON后端服务将根据URL或查询参数从数据库中删除记录。
  • 示例: 要删除ID为1的用户,你可以发送一个DELETE请求到/api/users/1。
bash 复制代码
DELETE /User/1

DEMO

流程

  • **项目设置:**首先,确保你的项目中已经引入了APIJSON的依赖。对于Java项目,你需要在pom.xml文件中添加APIJSON的依赖(参考文章1)。
  • **数据库配置:**按照APIJSON的要求,配置数据库连接信息(如URL、用户名、密码等)。在Demo中,这些信息通常位于配置文件中,如DemoSQLConfig.java(参考文章2)。
  • **数据表:**假设我们有一个名为users的数据表,包含id、name、age等字段。

pom.xml

xml 复制代码
	<!-- 需要的 APIJSON 相关依赖 -->
		<dependency>
			<groupId>com.github.Tencent</groupId>
			<artifactId>APIJSON</artifactId>
			<version>6.3.0</version>
		</dependency>
		<dependency>
			<groupId>com.github.APIJSON</groupId>
			<artifactId>apijson-framework</artifactId>
			<version>6.3.0</version>
		</dependency>

		<!-- 需要用的数据库 JDBC 驱动 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.29</version>
		</dependency>
		<!-- 需要用的 SpringBoot 框架,1.4.0 以上 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<version>2.5.13</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>2.0.43</version>
		</dependency>

application

java 复制代码
/*Copyright ©2016 TommyLemon(https://github.com/TommyLemon/APIJSON)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

package apijson.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import apijson.Log;
import apijson.framework.APIJSONApplication;
import apijson.framework.APIJSONCreator;
import apijson.orm.SQLConfig;
/**
 * Demo SpringBoot Application 主应用程序启动类
 */
@Configuration
@SpringBootApplication
@EnableConfigurationProperties
public class DemoApplication implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
  public static void main(String[] args) throws Exception {
    SpringApplication.run(DemoApplication.class, args);
    Log.DEBUG = true;
    APIJSONApplication.init(false);  
  }

  // SpringBoot 2.x 自定义端口方式
  @Override
  public void customize(ConfigurableServletWebServerFactory server) {
    server.setPort(8080);
  }

  // 支持 APIAuto 中 JavaScript 代码跨域请求
  @Bean
  public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
      @Override
      public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
          .allowedOriginPatterns("*")
          .allowedMethods("*")
          .allowCredentials(true)
          .maxAge(3600);
      }
    };
  }
  static {
    // 使用本项目的自定义处理类
    APIJSONApplication.DEFAULT_APIJSON_CREATOR = new APIJSONCreator<Long>() {
      @Override
      public SQLConfig createSQLConfig() {
        return new DemoSQLConfig();
      }
    };
  }
}

config

java 复制代码
/*Copyright ©2016 TommyLemon(https://github.com/TommyLemon/APIJSON)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

package apijson.demo;

import com.alibaba.fastjson.annotation.JSONField;

import apijson.framework.APIJSONSQLConfig;


/**SQL 配置 */
public class DemoSQLConfig extends APIJSONSQLConfig {

	static {
		DEFAULT_DATABASE = DATABASE_MYSQL;  // TODO 默认数据库类型,改成你自己的
		DEFAULT_SCHEMA = "apijson";  // TODO 默认数据库名/模式,改成你自己的,默认情况是 MySQL: sys, PostgreSQL: public, SQL Server: dbo, Oracle:
		//表名映射,隐藏真实表名,对安全要求很高的表可以这么做
		TABLE_KEY_MAP.put("User", "apijson_user");
		TABLE_KEY_MAP.put("Privacy", "apijson_privacy");
	}
	@Override
	public String getDBVersion() {
		return "5.7.22";  // "8.0.11";  // TODO 改成你自己的 MySQL 或 PostgreSQL 数据库版本号  // MYSQL 8 和 7 使用的 JDBC 配置不一样
	}
	@JSONField(serialize = false)  // 不在日志打印 账号/密码 等敏感信息
	@Override
	public String getDBUri() {
		return "jdbc:mysql://localhost:3306?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8"; // TODO 改成你自己的,TiDB 可以当成 MySQL 使用,默认端口为 4000
	}
	@JSONField(serialize = false)  // 不在日志打印 账号/密码 等敏感信息
	@Override
	public String getDBAccount() {
		return "root";  // TODO 改成你自己的
	}
	@JSONField(serialize = false)  // 不在日志打印 账号/密码 等敏感信息
	@Override
	public String getDBPassword() {
		return "123456";  // TODO 改成你自己的,TiDB 可以当成 MySQL 使用, 默认密码为空字符串 ""
	}
}

controller

java 复制代码
/*Copyright ©2016 TommyLemon(https://github.com/TommyLemon/APIJSON)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

package apijson.demo;

import java.net.URLDecoder;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import apijson.RequestMethod;
import apijson.StringUtil;
import apijson.framework.APIJSONController;
import apijson.orm.Parser;
/**请求路由入口控制器,包括通用增删改查接口等,转交给 APIJSON 的 Parser 来处理
 */
@RestController
@RequestMapping("")
public class DemoController extends APIJSONController<Long> {
	@Override
	public Parser<Long> newParser(HttpSession session, RequestMethod method) {
		return super.newParser(session, method).setNeedVerify(false);  // TODO 这里关闭校验,方便新手快速测试,实际线上项目建议开启
	}

	/**增删改查统一接口,这个一个接口可替代 7 个万能通用接口,牺牲一些路由解析性能来提升一点开发效率
	 */
	@PostMapping(value = "{method}")  // 如果和其它的接口 URL 冲突,可以加前缀,例如改为 crud/{method} 或 Controller 注解 @RequestMapping("crud")
	@Override
	public String crud(@PathVariable String method, @RequestBody String request, HttpSession session) {
		return super.crud(method, request, session);
	}

	/**全能增删改查接口,可同时进行 增、删、改、查 多种操作,
	 * 通过 @method: "POST", @gets: { "Privacy":"Privacy-CIRCLE", "User": { "@role":"LOGIN", "tag":"User" } } 等关键词指定
	 */
	@PostMapping(value = "crud")  // 直接 {method} 或 apijson/{method} 会和内置网页的路由有冲突
	// @Override
	public String crudAll(@RequestBody String request, HttpSession session) {
		return newParser(session, RequestMethod.CRUD).parse(request);
	}

	/**增删改查统一接口,这个一个接口可替代 7 个万能通用接口,牺牲一些路由解析性能来提升一点开发效率
	 */
	@PostMapping("{method}/{tag}")  // 如果和其它的接口 URL 冲突,可以加前缀,例如改为 crud/{method}/{tag} 或 Controller 注解 @RequestMapping("crud")
	@Override
	public String crudByTag(@PathVariable String method, @PathVariable String tag, @RequestParam Map<String, String> params, @RequestBody String request, HttpSession session) {
		return super.crudByTag(method, tag, params, request, session);
	}
}

初始化脚本

[初始化脚本](https://gitee.com/APIJSON/APIJSON-Demo/blob/master/MySQL/sys.sql)

请求样例

  1. 请求
bash 复制代码
curl --location --request POST 'http://localhost:8080/get' \
--header 'Content-Type: application/json' \
--data-raw '{
    "User[]":{
        "count":3,
        "User":[]
    }
}'
  1. 返回
java 复制代码
{
    "User[]": [
        [],
        {
            "$ref": "$.User\\[\\][0]"
        },
        {
            "$ref": "$.User\\[\\][0]"
        }
    ],
    "ok": true,
    "code": 200,
    "msg": "success",
    "debug:info|help": " \n提 bug 请发请求和响应的【完整截屏】,没图的自行解决! \n开发者有限的时间和精力主要放在【维护项目源码和文档】上! \n【描述不详细】 或 【文档/常见问题 已有答案】 的问题可能会被忽略!! \n【态度 不文明/不友善】的可能会被踢出群,问题也可能不予解答!!! \n\n **环境信息**  \n系统: Windows 10 10.0 \n数据库: DEFAULT_DATABASE = MYSQL \nJDK: 1.8.0_101 amd64 \nAPIJSON: 6.3.0 \n   \n【常见问题】:https://github.com/Tencent/APIJSON/issues/36 \n【通用文档】:https://github.com/Tencent/APIJSON/blob/master/Document.md \n【视频教程】:https://search.bilibili.com/all?keyword=APIJSON",
    "time": 1717495293436,
    "sql:generate|cache|execute|maxExecute": "0|0|0|200",
    "depth:count|max": "2|5",
    "time:start|duration|end|parse|sql": "1717495293434|2|1717495293436|2|0"
}
相关推荐
ZJ_.3 分钟前
Node.js 使用 gRPC:从定义到实现
java·开发语言·javascript·分布式·rpc·架构·node.js
基哥的奋斗历程3 分钟前
springboot整合Camunda实现业务
java·spring boot·dubbo
dot.Net安全矩阵5 分钟前
.NET 漏洞分析 | 某ERP系统存在SQL注入
数据库·sql·安全·web安全·矩阵·.net
hummhumm43 分钟前
数据结构第08小节:双端队列
java·数据结构·spring boot·spring·java-ee·maven·intellij-idea
六月的雨__1 小时前
二手物品交易小程序的设计
java·sql·学习·小程序
夏天想2 小时前
微服务架构是什么?他有什么优缺点。其实的安全问题如何解决?
安全·微服务·架构
dot.Net安全矩阵2 小时前
.NET 漏洞情报 | 某整合管理平台SQL注入
数据库·sql·安全·矩阵·.net
都适、隶仁ミ2 小时前
SQL注入工具Sqlmap
linux·网络·数据库·sql·安全·网络安全·系统安全
地瓜伯伯3 小时前
HandlerMethodArgumentResolver :深入spring mvc参数解析机制
大数据·人工智能·spring boot·spring·语言模型