广州企业网站建设方案,竞争对手网站分析,铜川做网站电话,广州有哪些网络设计公司graphql“ GraphQL是API的查询语言#xff0c;是用于使用现有数据完成这些查询的运行时。 GraphQL为您的API中的数据提供了完整且易于理解的描述#xff0c;使客户能够准确地询问他们所需的内容#xff0c;仅此而已#xff0c;使随着时间的推移更容易开发API并启用强大的开… graphql “ GraphQL是API的查询语言是用于使用现有数据完成这些查询的运行时。 GraphQL为您的API中的数据提供了完整且易于理解的描述使客户能够准确地询问他们所需的内容仅此而已使随着时间的推移更容易开发API并启用强大的开发人员工具。” –来自https://graphql.org/ 任何已经建立了可供多个消费者使用的REST服务的人例如其他服务网站或移动设备都会知道很难建立一个能够满足所有需求的完美端点。 对于所有这些特殊情况您通常最终都会获得相同服务的变体) 现在我们都知道我们应该只使用HATEOAS …它在我的TODO列表中承诺直到我偶然发现GraphQL为止 。 因此在这篇博客文章中我将解释如何轻松地将GraphQL添加到现有的JAX-RS应用程序中。 示例项目 Github中提供了示例项目并且非常容易上手。 git clone https://github.com/phillip-kruger/membership.git
cd membership
mvn clean install 这将使用示例应用程序http// localhost8080 / membership /来启动fatjar wildfly-swarm 高水平 该示例是基本的成员资格服务您可以在其中获得所有成员或特定成员。 您可以添加编辑和删除成员。 该应用程序是典型的JAX-RSCDIEJBJPABean验证Java EE应用程序我们将添加一个新的GraphQL端点。 GraphQL部分使用以下库 graphql-java graphql-java-servlet graphQL-spqr 石墨烯 我添加来将现有的JAX-RS公开为GraphQL的唯一Java类 MembershipGraphQLListener –注册“ / graphql” Servlet侦听器。 MembershipGraphQLApi – GraphQL端点。 仅包装现有的Stateless服务。 MembershipErrorHandler –处理异常。 使用graphQL-spqr的注释 MembershipGraphQLApi类实际上只是描述和包装了现有的Stateless服务 RequestScopedpublic class MembershipGraphQLApi {Injectprivate MembershipService membershipService;// ...GraphQLQuery(name memberships)public ListMembership getAllMemberships(OptionalMembershipFilter filter,GraphQLArgument(name skip) OptionalInteger skip,GraphQLArgument(name first) OptionalInteger first) {return membershipService.getAllMemberships(filter, skip, first); }// ...} 我的希望–我们很快将在Java EE或Jakarta EE或MicroProfile中提供一个JAX-QL或其他东西以使其变得更加简单 首先是一些REST 我正在使用MicroProfile OpenAPI和Swagger UI为REST端点创建Open API定义。 您可以使用http// localhost8080 / membership / rest / openapi-ui /测试一些查询 示例 –获取所有成员资格 GET http://localhost:8080/membership/rest 这将返回 [{membershipId: 1,owner: {id: 1,names: [Natus,Phillip],surname: Kruger},type: FULL},{membershipId: 2,owner: {id: 2,names: [Charmaine,Juliet],surname: Kruger},type: FULL},{membershipId: 3,owner: {id: 3,names: [Koos],surname: van der Merwe},type: FULL},{membershipId: 4,owner: {id: 4,names: [Minki],surname: van der Westhuizen},type: FREE}] 示例 –获得一定的成员资格1 GET http://localhost:8080/membership/rest/1 这将返回 {membershipId: 1,owner: {id: 1,names: [Natus,Phillip],surname: Kruger},type: FULL}现在让我们看一下GraphQL 该应用程序包括GraphiQL UI作为Webjar可以轻松测试某些GraphQL查询 您可以使用http// localhost8080 / membership / graph / graphiql /测试一些查询 因此让我们来看看GraphQL是否兑现了“不再需要过度提取和提取不足”的承诺。 获取所有成员资格和所有字段与REST相同 query Memberships {memberships{...fullMembership}}fragment fullMembership on Membership {membershipIdowner{...owner}type}fragment owner on Person {idnamessurname } 这将返回所有值但是现在很容易定义应包括哪些字段… 获取所有会员资格但仅包括id字段 query Memberships {memberships{...membershipIdentifiers}}fragment membershipIdentifiers on Membership {membershipId} 现在产生的有效负载要小得多 {data: {memberships: [{membershipId: 1},{membershipId: 2},{membershipId: 3},{membershipId: 4}]}}现在仅获取特定类型的会员资格因此获取所有免费会员资格 query FilteredMemberships {memberships(filter:{type:FREE}){...fullMembership}}fragment fullMembership on Membership {membershipIdowner{...owner}type}fragment owner on Person {idnamessurname } 这将仅返回免费会员资格。 好酷 甚至更好所有姓氏的成员都以“ Kru”开头 query FilteredMemberships {memberships(filter:{surnameContains: Kru}){...fullMembership}}fragment fullMembership on Membership {membershipIdowner{...owner}type}fragment owner on Person {idnamessurname } 太好了 我们找到了两个人 {data: {memberships: [{membershipId: 1,owner: {id: 1,names: [Natus,Phillip],surname: Kruger},type: FULL},{membershipId: 2,owner: {id: 2,names: [Charmaine,Juliet],surname: Kruger},type: FULL}]}}使用客户端上的变量获取特定成员资格 query Membership($id:Int!) {membership(membershipId:$id){...fullMembership}}fragment fullMembership on Membership {membershipIdowner{...owner}type}fragment owner on Person {idnamessurname } 变量 {id:1}在特定条件下包括字段 query Membership($id:Int!,$withOwner: Boolean!) {membership(membershipId:$id){...fullMembership}}fragment fullMembership on Membership {membershipIdowner include(if: $withOwner){...owner}type}fragment owner on Person {idnamessurname } 变量 {id:1,withOwner: false} 这将排除所有者正确包括 {data: {membership: {membershipId: 1,type: FULL}}}分页 让我们使用get all查询但要分页。 query Memberships($itemsPerPage:Int!,$pageNumber:Int!) {memberships(first:$itemsPerPage,skip:$pageNumber) {membershipIdowner{namessurname}type}} 变量 {itemsPerPage: 2,pageNumber: 1} 这将返回前2个结果然后您可以通过增加“ pageNumber”值来进行分页。 变异 创造 mutation CreateMember {createMembership(membership: {type:FULL,owner: {names: James,surname:Small}}) {membershipId}} 这将创建新的成员资格并返回ID。 更新资料 mutation EditMember($membership: MembershipInput!) {createMembership(membership:$membership) {membershipId}} 变量 {membership: {membershipId: 2,owner: {names: [Charmaine,Juliet],surname: Krüger},type: FULL}} 在克鲁格大学添加了变音符号现在应该是克鲁格 删除 mutation DeleteMembership($id:Int!){deleteMembership(membershipId:$id){membershipId}} 变量 {id:1} 这将删除成员资格1。 例外。 MembershipErrorHandler转换一个ConstraintViolationException在bean验证失败时引发并为GraphQL创建一个不错的错误消息。 因此让我们尝试创建一个姓氏仅为一个字母的成员。 mutation CreateMember($membership: MembershipInput!) {createMembership(membership:$membership) {membershipId}} 变量 {membership: {owner: {names: Christina,surname: S},type: FULL}} 这将返回bean验证错误消息 {data: {createMembership: null},errors: [{message: Surname S is too short, minimum 2 characters,path: null,extensions: null}]} 如果您查看Person POJO NotNull(message Surname can not be empty) Size(min2, message Surname ${validatedValue} is too short, minimum {min} characters)private String surname;内省 GraphQL的另一个好处是它具有可查询的架构和类型系统 {__schema {queryType {namefields {name}}mutationType{namefields{name}}subscriptionType {namefields{name}}}} 上面将描述此端点上可用的查询和变异。 您还可以描述您的模型 {__type(name: Membership) {namekindfields {nameargs {name}}}}摘要 在此示例中我们没有删除REST只是添加了GraphQL作为使用者的替代选项。 到现在为止应该清楚的是客户端还有更多的选项可以完全根据需要过滤和查询数据。 所有这些都无需服务器做任何额外的工作。 这样可以在客户端进行快速的产品迭代。 线上的有效负载已得到优化我们正在节省带宽 再次我希望–我们很快将在Java EE或Jakarta EE或MicroProfile中提供一个JAX-QL或其他东西以使其变得更加简单 翻译自: https://www.javacodegeeks.com/2018/05/graphql-on-wildfly-swarm.htmlgraphql