首页 > 其他分享 >GraphQL使用

GraphQL使用

时间:2022-12-28 18:13:37浏览次数:37  
标签:String private id amount GraphQL 使用 currentPlayer name

GraphQL使用

1. 介绍

GraphQL是一个开源的,面向API而创造出来的数据查询操作语言以及相应的运行环境。

GraphQL给客户端自主选择数据内容的能力,客户端完全自主决定获取信息的内容,服务端负责精确的返回目标数据。

 

我们经常会在某个需求中需要调用多个独立的API接口才能获取到足够的数据,例如客户端要去显示一篇文章的内容,同时也要显示评论、作者信息,那么就可能需要调用文章接口、评论接口、用户接口。这种方式非常的不灵活。另一个case是很多项目都会去拉一些不同的配置文件来决定展示什么,比如我们业务里的app,一打开就有10多个请求,非常不合理,不仅多个请求浪费了带宽,而且速度慢,客户端处理的请求也复杂。

 

2. graphql-server-demo服务端

2.1 graphql定义文件

player.graphqls

type Player {
    id: ID!
    name: String!
    points: Int!
    inventory: [Item!]!
    billing: Billing!
}

type Billing {
    balance: String!    # decimal string...
    operations: [Operation!]!
}

type Operation {
    amount: String!    # decimal string...
    description: String
}

type Item {
    name: String!
}

type Query {

    currentPlayer(id: ID!): Player!

    currentPlayerAll: [Player!]!
}

  

2.2 调用4个独立API接口获取数据

@RequiredArgsConstructor
class Player {

    private final Integer id;

    private final BillingRepository billingRepository;
    private final InventoryClient inventoryClient;
    private final PlayerMetadata playerMetadata;
    private final PointsCalculator pointsCalculator;

    CompletableFuture<Billing> billing() {
        return billingRepository.forUser(id);
    }

    CompletableFuture<String> name() {
        return playerMetadata.lookupName(id);
    }

    CompletableFuture<Integer> points() {
        return pointsCalculator.pointsOf(id);
    }

    CompletableFuture<List<Item>> inventory() {
        return inventoryClient.loadInventory(id);
    }
}

  

2.3 API接口实现 - 获取player名称

@Component
@RequiredArgsConstructor
class PlayerMetadata {

    private final ExecutorService playerExecutor;

    private final Fairy fairy;

    CompletableFuture<String> lookupName(Integer playerId) {
        return CompletableFuture.supplyAsync(() -> {
            Sleeper.sleep(Duration.ofMillis(100));
            return fairy.person().getFirstName()+"_id_"+playerId;
        }, playerExecutor);
    }
}

  

3. graphql客户端

3.1 currentPlayerAll获取player数据列表

requestBody数据格式

{
  currentPlayerAll {
    id
    name
    points
    inventory {
      name
    }
    billing {
      balance
      operations {
        amount
        description
      }
    }
  }
}

 

@Log4j2
public class graplql_01 {

    private static final String CONTENT_TYPE = "application/graphql";

    public static void main(String... args) throws Exception {
        String id = invokeRemoteService("currentPlayerAll",11L);
        log.info("--------, id = "+id);

//        String id2 = invokeRemoteService("currentPlayer",11L);
//        log.info("--------, id = "+id2);
    }

    private static String invokeRemoteService(String methodName, Long traceId) throws Exception {
        String url = "http://127.0.0.1:8080/graphql";

        // create an instance of RestTemplate
        RestTemplate restTemplate = new RestTemplate();

        // create headers
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.valueOf(CONTENT_TYPE));// set `content-type` header

        // request body parameters

        // build the request
        String requestBody = null;
        if("currentPlayerAll".equals(methodName)){
            requestBody = readRequestBody();
        }else if("currentPlayer".equals(methodName)){
            requestBody = readRequestBodyById();
        }
        HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);

        // send POST request
        ResponseEntity<Object> response = restTemplate.postForEntity(url, entity, Object.class);

        // check response
        if (response.getStatusCode() == HttpStatus.CREATED || response.getStatusCode() == HttpStatus.OK) {
            log.info("Request [" + traceId + "] Successful 200 content = \n" + JSON.toJSONString(response.getBody(),true));
            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(response.getBody()));
            JSONObject data = jsonObject.getJSONObject("data");
            String ids = "";
            if("currentPlayerAll".equals(methodName)){
                JSONArray currentPlayers = data.getJSONArray(methodName);
                /**获取id列表**/
                List<String> playerIds = Arrays.stream(currentPlayers.toArray()).map(f -> ((JSONObject)f).getString("id")).collect(Collectors.toList());

                String playerIdsStr = playerIds.stream().collect(Collectors.joining("::"));
                ids = playerIdsStr;

            }else if("currentPlayer".equals(methodName)){
                JSONObject currentPlayer = data.getJSONObject(methodName);
                ids = currentPlayer.getString("id");
            }

            return ids;
        } else {
            log.info("Request [" + traceId + "] Failed [" + response.getStatusCode() + "] content = " + response.getBody());
            return "-1";
        }
    }

    private static String readRequestBody() throws URISyntaxException, IOException {
        Stream<String> lines = Files.lines(
                Paths.get(ClassLoader.getSystemResource("request_body.txt").toURI()));

        return lines.collect(Collectors.joining());
    }

    private static String readRequestBodyById() throws URISyntaxException, IOException {
        Stream<String> lines = Files.lines(
                Paths.get(ClassLoader.getSystemResource("request_body2.txt").toURI()));

        return lines.collect(Collectors.joining());
    }
}

  

调用结果:

{
	"data":{
		"currentPlayerAll":[
			{
				"id":"1315563916",
				"name":"Nicholas_id_1315563916",
				"points":42,
				"inventory":[
					{
						"name":"Sword"
					},
					{
						"name":"Sword"
					}
				],
				"billing":{
					"balance":"10",
					"operations":[
						{
							"amount":"10",
							"description":"Item purchase"
						},
						{
							"amount":"1",
							"description":"Item purchase"
						}
					]
				}
			},
			{
				"id":"269998305",
				"name":"Luke_id_269998305",
				"points":42,
				"inventory":[
					{
						"name":"Shoes"
					},
					{
						"name":"Shoes"
					}
				],
				"billing":{
					"balance":"10",
					"operations":[
						{
							"amount":"10",
							"description":"Item purchase"
						},
						{
							"amount":"1",
							"description":"Item purchase"
						}
					]
				}
			}
		]
	}
}

  

 

3.2 currentPlayer获取某个ID对应的player数据

requestBody数据格式

{
  currentPlayer(id: 11) {
    id
    name
    points
    inventory {
      name
    }
    billing {
      balance
      operations {
        amount
        description
      }
    }
  }
}

  

调用结果:

{
	"data":{
		"currentPlayer":{
			"id":"11",
			"name":"Aaron_id_11",
			"points":42,
			"inventory":[
				{
					"name":"Potion"
				},
				{
					"name":"Shoes"
				}
			],
			"billing":{
				"balance":"10",
				"operations":[
					{
						"amount":"10",
						"description":"Item purchase"
					},
					{
						"amount":"1",
						"description":"Item purchase"
					}
				]
			}
		}
	}
}

  

 

3.3 currentPlayer获取不同格式的player数据

requestBody数据格式

{
  currentPlayer(id: 11) {
    id
    name
    points
    billing {
      balance
      operations {
        amount
      }
    }
  }
}

调用结果:

{
	"data":{
		"currentPlayer":{
			"id":"11",
			"name":"Allison_id_11",
			"points":42,
			"billing":{
				"balance":"10",
				"operations":[
					{
						"amount":"10"
					},
					{
						"amount":"1"
					}
				]
			}
		}
	}
}

 

标签:String,private,id,amount,GraphQL,使用,currentPlayer,name
From: https://www.cnblogs.com/sanqianyuejia/p/17010923.html

相关文章

  • 微软Azure创建免费虚拟机使用
    前言首先你要有一个可以申请azure100的教育邮箱,这里不做过多介绍申请前往这个链接使用你的邮箱申请azure100注意最好使用浏览器无痕访问手机号码填写自己的https://a......
  • 使用Py的多线程爬取P站,老司机慎入。
    hello呀,小伙伴们,今个给大家带来的是爬取P站的教程,别搞错,这个不是你想的那个p站。这样想肯定是你用黄黄的思想点进来的。众所周知,P站是个插画网站,也包含一些R18的插画。停停......
  • 使用py一键获取所有必应壁纸图片
    Bing壁纸一直以来都是WIN7系统里的不可或缺的一道亮丽风景线,其高清、唯美、微妙镜头下的风景一直有着专业、不可比拟的称赞。Bing壁纸汇集了山水风景壁纸里各式各样的精华,再......
  • 使用xpath爬取对应百度贴吧下面的帖子图片
    hello,小伙伴们,上次给大家分享了如何使用python的正则匹配爬取百思不得姐的网站代码,虽然说正则匹配爬取网站的执行效率高,但是正则匹配的规则编写着实是令人头痛的一件事。今......
  • 【Python 库】bs4的使用
    和lxml一样,BeautifulSoup也是一个HTML/XML的解析器,主要的功能也是如何解析和提取HTML/XML数据。BeautifulSoup,是一个第三方的库,所以使用之前需要安装,安装方法,输入cmd,调出......
  • Python中使用xpath一键获取各国国旗
    国旗是一个国家的主权意识不断增强后必然的产物,国旗是国家的一种标志性旗帜,是国家的象征。代表着一个国家的主权和民族的尊严。每个国家的国旗都由特有的颜色和图案构成,这些......
  • 使用py爬取复产后的鹅厂都在招聘哪些职位
    hello呀,各位小伙伴,今天是五月的第二天,不知道大家是在家里wifi,空调,西瓜呢,还是在拥挤的景区看着人山人海!反正小编是穿着大裤衩,坐在马路边的沙滩上,啜一口摆在身边的饮料,享受......
  • 使用Python的asyncio模块异步下载整站壁纸
    这篇文章主要给大家介绍关于Python中asyncio模块的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Python具有一定的参考学习价值,需要的朋友们下面来一起学习学......
  • 使用python爬取B站视频
    B站之所以火,是因为趣味与知识并存。正如一句“你在B站看番,我在B站学习”,B站还是有一些质量比较好的学习视频。当你在B站上看到喜欢的视频想保存下来时,怎么办呢?我相信很多逛B......
  • pinia的简单使用
    //安装//yarnaddpinia//在main.js中import{createPinia}from'pinia'constpinia=createPinia()app.use(pinia)//创建src/store/index.jsimport{d......