目录
初识Hasura和周边
开门见山说重点
个人理解
使用经验
hasura介绍
API接口性能的描述
how work
action业务逻辑
授权
鉴权
docker安装
其他
Hasura |
graphQL规范的一种实现,作为graphQL服务器。 |
GraphQL |
GraphQL | A query language for your API GraphQL 是一种API规范,是一个基于类型系统来执行查询的服务端运行时。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。 个人理解:图查询语言 用于检索数据的api查询语言 类比restful规范,用于定义接口;理解为是一种规范,如sql,结构性查询语言,与具体数据库无关。 类型系统:由自定义的各种数据模型构成,包括对象类型、标量、枚举、列表、接口、输入类型等。 最佳实践:通过单入口提供http服务的完整功能,返回json形式。 |
postgresql |
对象关系型数据库 docker run --name postgres -p 5432:5432 -e POSTGRES_PASSWORD=chl_postgre -d postgres su postgres createdb mydb |
举例:hasura自动生成的graphQL API
url |
http://host:port/v1/graphql |
method |
post |
header |
Content-Type = application/json; charset=utf-8 |
body |
查询举例: {"query":"query queryAuthor {chl_t_author {id age desc name}}"} |
编辑举例: {"query":"mutation MyMutation {insert_chl_t_mv(objects: {author_id: 1, desc: \"mv描述\", name: \"mv14\"}) {returning {id}}}"} |
可创建单条,多条数据,如单个商品、多个商品
可以同时创建具有外键关系的多条记录,如商品和类目有外键关系,可创建类目同时创建一个商品,要求外键不赋值
例如:执行效果,新建类目记录,商品外键类目id被赋值
mutation MyMutation {
insert_chl_t_category(objects: {img: "https://www.itoumi.com/img/home-text.6c72e2f8.png", name: "跳蚤市场", sort: 10, t_base_infos: {data: {content: "跳蚤市场内容xxxx", first_img: "https://www.itoumi.com/img/home-text.6c72e2f8.png", key_desc: "二手 二手", mobile: "13277777777", price: "1999", small_imgs: "https://www.itoumi.com/img/home-text.6c72e2f8.png,https://www.itoumi.com/img/home-text.6c72e2f8.png", title: "跳蚤市场二手01", user_id: 6, recommend_days: 10, service_fee: "10", province_id: 110000, city_id: 110100, county_id: 110101}}}) {
returning {
id
t_base_infos {
id
}
}
}
}
哈苏拉 Instant GraphQL APIs on your data | Built-in Authz & Caching
hasura作为graphql服务器,hasura引擎自动基于连接的数据库生成graphql schema,restful接口,GraphQL接口。从API到读写DB都不需要人为编写代码,需要人为介入的有db table的定义,action内容,api调用。
特点包括支持多种数据库、快速从数据库生成统一的生产环境级别的API、API接口性能高等。
为自定义(部署hasura自动生成的)的graphQLAPI提供了访问业务逻辑RestAPI的方式。
例如由RestAPI负责验证、处理或丰富数据,亦或者调用其他API,亦或者用户登录。action可以处理请求和返回值的数据、可以异步返回值graphql客户端。
创建action
Action Definition |
自定义graphQL |
Type Configuration |
自定义graphQL中用到的模型,入参类型用input修饰,其他类型用type修饰 |
Webhook (HTTP/S) Handler |
RestFul API 地址 必须填写http或https |
Change Request Options |
设置rest api request,如method 参数映射 |
Change Payload |
组织rest api body信息,只post需要 |
Change Response |
返回结果映射 |
代码生成:提供rest api代码模板,例如notejs提供rest api
action仅负责配置自定义grapql api与外部rest api的关系,此时action配置无法对表数据进行新增和修改,只能通过rest api写数据(业务逻辑中再次调用graphQL api),action可以通过返回值关联查询出数据。
需要依赖外部的授权服务器。例如jwt:访问外部的授权服务器,或action,授权结果放在header Authorization,hasura进行鉴权。
启动配置项 |
HASURA_GRAPHQL_JWT_SECRET |
jwt claim内容必须包括的数据项 |
x-hasura-allowed-roles 用户具有的角色 x-hasura-default-role 默认角色 |
请求header携带授权信息 |
Authorization Bearer +jwt |
其他header |
x-Hasura-Role 访问当前graphQL api应具有的角色 |
Authorization |
Bearer eyJhbGciOiJIUzI1NiJ9.eyJodHRwczovL2hhc3VyYS5pby9qd3QvY2xhaW1zIjp7IngtaGFzdXJhLWRlZmF1bHQtcm9sZSI6ImFub255bW91cyIsIngtaGFzdXJhLXVzZXItaWQiOiI2IiwieC1oYXN1cmEtYWxsb3dlZC1yb2xlcyI6WyJ1c2VyMSIsImVkaXRvciJdfX0.NdIKwk9wCpt_6xwag_yQzZTs1zA3P68XCDLF_1egxDM |
jwt claim |
"x-hasura-allowed-roles", ["user1", "editor"] "x-hasura-default-role", "anonymous" "x-hasura-user-id", "6" |
访问效果 |
鉴权举例:具有角色且满足数据权限过滤条件。
Authorization |
Bearer eyJhbGciOiJIUzI1NiJ9.eyJodHRwczovL2hhc3VyYS5pby9qd3QvY2xhaW1zIjp7IngtaGFzdXJhLWRlZmF1bHQtcm9sZSI6InVzZXIxIiwieC1oYXN1cmEtdXNlci1pZCI6IjYiLCJ4LWhhc3VyYS1hbGxvd2VkLXJvbGVzIjpbInVzZXIiLCJlZGl0b3IiXX19.idFmUt-tPzcw2LkTuHX5MlN-JkEw8aBh6HQIIcLHeRw |
jwt claim |
"x-hasura-allowed-roles", ["user", "editor"] "x-hasura-default-role", "anonymous" "x-hasura-user-id", "6" |
权限配置 |
t_user表 user角色具有select权限,且添加数据过滤条件 id = header中x-hasura-user-id |
访问效果 |
鉴权结果:角色满足但是无数据
Authorization |
Bearer eyJhbGciOiJIUzI1NiJ9.eyJodHRwczovL2hhc3VyYS5pby9qd3QvY2xhaW1zIjp7IngtaGFzdXJhLWRlZmF1bHQtcm9sZSI6ImFub255bW91cyIsIngtaGFzdXJhLXVzZXItaWQiOiI4MCIsIngtaGFzdXJhLWFsbG93ZWQtcm9sZXMiOlsidXNlciIsImVkaXRvciJdfX0.kVXOMQYpzdKJ44abF_cUXdY8rJFazf4n2MhcOMz5lrQ |
jwt claim |
"x-hasura-allowed-roles", ["user", "editor"] "x-hasura-default-role", "anonymous" "x-hasura-user-id", "80" |
访问效果 |
io.jsonwebtoken
jjwt-api
0.11.5
io.jsonwebtoken
jjwt-impl
0.11.5
runtime
io.jsonwebtoken
jjwt-jackson
0.11.5
runtime
static final String jwtSecretString = "S22zAIgXiQmMoywh/jGzm3Tx4o/M74UVarnFKbqNSBc=";
static String jwt() {
Map hasuraClaim = new HashMap<>();
hasuraClaim.put("x-hasura-allowed-roles", new String[]{"user", "editor"});
hasuraClaim.put("x-hasura-default-role", "anonymous");
hasuraClaim.put("x-hasura-user-id", "80");
SecretKey key = Keys.hmacShaKeyFor(jwtSecretString.getBytes(StandardCharsets.UTF_8));
String compact = Jwts.builder().claim("https://hasura.io/jwt/claims", hasuraClaim).signWith(key, SignatureAlgorithm.HS256)
.compact();
Jws claimsJws = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(compact);
return compact;
}
不是提供公共服务,则需要添加admin环境配置。
匿名访问
提供基于角色的数据操作权限控制,为角色分配数据表、字段的crud权限。
使用上,必须在request header中携带角色信息,否则角色控制失效。
例如header X-Hasura-Role=user,角色user的权限控制才生效。
不使用jwt:
docker run --name chl_hasura_adminsecret -d -p 8080:8080 -e HASURA_GRAPHQL_DATABASE_URL=postgres://postgres:[email protected]:5432/mydb -e HASURA_GRAPHQL_ENABLE_CONSOLE=true -e HASURA_GRAPHQL_ADMIN_SECRET=xxxadminsecret -e HASURA_GRAPHQL_UNAUTHORIZED_ROLE=anonymous hasura/graphql-engine:latest
使用jwt:
以下脚本添加jwt配置,启动失败,网络和官网搜不到原因。最终使用docker-compose.yaml,不报错。
(Environment variable HASURA_GRAPHQL_JWT_SECRET: Error in $: object key > 34: Failed reading: satisfy)
docker run --name chl_hasura_adminsecret_jwt -d -p 8080:8080 -e HASURA_GRAPHQL_DATABASE_URL=postgres://postgres:[email protected]:5432/mydb -e HASURA_GRAPHQL_ENABLE_CONSOLE=true -e HASURA_GRAPHQL_ADMIN_SECRET=xxxadminsecret -e HASURA_GRAPHQL_UNAUTHORIZED_ROLE=anonymous -e HASURA_GRAPHQL_JWT_SECRET="{'type':'HS256', 'key':'S22zAIgXiQmMoywh/jGzm3Tx4o/M74UVarnFKbqNSBc='}" hasura/graphql-engine:latest
version: '3.6'
services:
postgres:
image: postgres
restart: always
environment:
POSTGRES_PASSWORD: chl_postgre
POSTGRES_USER: postgres
volumes:
- db_data:/var/lib/postgresql/data
graphql-engine:
image: hasura/graphql-engine:latest
ports:
- "8080:8080"
depends_on:
- "postgres"
restart: always
environment:
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:[email protected]:5432/mydb
HASURA_GRAPHQL_ENABLE_CONSOLE: "true"
HASURA_GRAPHQL_ADMIN_SECRET: xxxadminsecret
HASURA_GRAPHQL_UNAUTHORIZED_ROLE: anonymous
HASURA_GRAPHQL_JWT_SECRET: '{"type":"HS256","key":"S22zAIgXiQmMoywh/jGzm3Tx4o/M74UVarnFKbqNSBc="}'
volumes:
db_data:
访问graphql mutation接口时出现invalid query错误
原因为:提交的json中key不可以使用"或'包裹,例如{‘key’:val}{"key":val},这样都会报错。
解决方式:客户端json key加前后缀,对json str进行替换。
var baseInfo = JSON.stringify(this.data.baseInfo).replace("\"prefix_", "").replace("_suffix\"", "")
while(baseInfo.includes("prefix_")){
baseInfo = baseInfo.replace("\"prefix_", "").replace("_suffix\"", "")
}
var operationsDoc = `
mutation MyMutation {
insert_chl_t_base_info_one(object: `+baseInfo+`) {
id
}
}
`;
jwt配置问题
转为使用docker-compose.yaml文件
Spring提供了对graphQL的支持,负责结合graphQL java与Spring引擎。
开发者需要做的事情:按照graphQL规范定义类型系统、graphQL api;java编写controller,可自由实现业务逻辑。
docker安装
docker run --name chl_pgadmin -d -p 8082:80 -e [email protected] -e PGADMIN_DEFAULT_PASSWORD=123456 dpage/pgadmin4:latest