DrillLab
练习Practice

动手做Get your hands on it

练习跟着课文走 —— 每节课尾都有本课的练习。这一页是全部练习的总库,想集中刷题的时候来。 每个练习都写清了它来自哪一节,卡住了就回去看那一节。Practice follows the lessons — every lesson ends with the exercises for that lesson. This page is the whole library, for when you want to drill in one sitting. Each exercise names the lesson it came from, so you can go back when you stall.

0 / 148个做对过you got right
筛一下Filter theseFederation 考试Federation examL2L2Debug LabDebug Lab
难度LevelL1 → L4 和上面四档同一个意思:给你的东西越来越少L1 → L4: the same idea as the four tiers above — less is handed to you全部难度All levelsL1L1L2L2L3L3L4L4

已筛到你正在学的《Federation 考试》。想看全部就点上面的「全部」。Filtered to Federation exam — the course you are on. Use “All” above to see everything.

练习Exercises

筛出 3 个练习(共 148 个)。Showing 3 of 148.
来自From N+1 问题与 DataLoaderThe N+1 problem and DataLoader · Federation 考试Federation exam
L2Debug LabDebug LabDebug Lab · DataLoader 报 is not a functionDebug Lab · DataLoader reports is not a function

npm test,其中一个 DataLoader 相关的测试挂了。 报错指向 loader 内部。

You run npm test and one of the DataLoader tests fails. The error points inside the loader.

第 1 步 · 先看现象和代码,别急着改Step 1 · read the symptom and the code before you touch anything
● Order Resolvers › DataLoader functionality › should batch multiple order requests TypeError: orderDataSource.getOrderById is not a function 29 | 30 | const orders = await Promise.all( > 31 | orderIds.map(id => orderDataSource.getOrderById(id)) | ^ 32 | ); 33 | 34 | return orders; at src/resolvers/orderResolvers.js:31:42 at Array.map (<anonymous>) at DataLoader._batchLoadFn (src/resolvers/orderResolvers.js:31:16)
JavaScriptsrc/resolvers/orderResolvers.js示意Illustrative
1function createOrderLoader(orderDataSource) {
2 return new DataLoader(async orderIds => {
3 const orders = await Promise.all(
4 orderIds.map(id => orderDataSource.getOrderById(id))
5 );
6 return orders;
7 });
8}
9
10// 参考:OrderDataSource 上真实存在的方法
11// class OrderDataSource {
12// async getOrder(id) { ... }
13// async getOrdersByUserId(userId) { ... }
14// async createOrder(userId, items) { ... }
15// }
1function createOrderLoader(orderDataSource) {
2 return new DataLoader(async orderIds => {
3 const orders = await Promise.all(
4 orderIds.map(id => orderDataSource.getOrderById(id))
5 );
6 return orders;
7 });
8}
9
10// For reference: the methods OrderDataSource really has
11// class OrderDataSource {
12// async getOrder(id) { ... }
13// async getOrdersByUserId(userId) { ... }
14// async createOrder(userId, items) { ... }
15// }
第 2 步 · 这是什么类型的错误Step 2 · what kind of error is this
来自From Debug Lab · Federation 十种典型故障Debug Lab · ten common Federation failures · Federation 考试Federation exam
L2Debug LabDebug Lab故障 2 · Cannot return null for non-nullable fieldFault 2 · Cannot return null for non-nullable field

查一个没有订单的用户,整个 data 变成了null,而且 errors 里有一条很长的消息。

You query a user who has no orders, the whole data turns into null, and errors carries one very long message.

第 1 步 · 先看现象和代码,别急着改Step 1 · read the symptom and the code before you touch anything
$ node verify-schema.mjs Query.orders: {"orders":null} errors: [{ "message": "Cannot return null for non-nullable field Query.orders.", "path": ["orders"], "extensions": { "code": "INTERNAL_SERVER_ERROR" } }] # 更严重的情况:如果查询是嵌套的,整个 data 会变成 null$ node verify-schema.mjs Query.orders: {"orders":null} errors: [{ "message": "Cannot return null for non-nullable field Query.orders.", "path": ["orders"], "extensions": { "code": "INTERNAL_SERVER_ERROR" } }] # Worse case: if the query is nested, the whole data object turns into null
JavaScriptsrc/resolvers/orderResolvers.js示意Illustrative
1async orders(_, { userId }, { dataSources, correlationId }) {
2 const orders = await dataSources.orderDataSource.getOrdersByUserId(userId);
3 return orders; // 数据源可能返回 undefined
4}
5
6// 参考 schema.graphql:
7// type Query {
8// orders(userId: ID!): [Order!]! ← 双重非空
9// }
1async orders(_, { userId }, { dataSources, correlationId }) {
2 const orders = await dataSources.orderDataSource.getOrdersByUserId(userId);
3 return orders; // the data source may return undefined
4}
5
6// For reference, schema.graphql says:
7// type Query {
8// orders(userId: ID!): [Order!]! ← non-null twice
9// }
第 2 步 · 这是什么类型的错误Step 2 · what kind of error is this
来自From Debug Lab · Federation 十种典型故障Debug Lab · ten common Federation failures · Federation 考试Federation exam
L2Debug LabDebug Lab故障 4 · PATCH 传了小写状态,返回 500Fault 4 · PATCH sends a lowercase status and gets a 500

Java 那边。mvn test 全过, 但客户端传小写的 shipped 时服务返回 500。

This one is on the Java side. mvn test passes everything, but the service returns 500 when the client sends the lowercase shipped.

第 1 步 · 先看现象和代码,别急着改Step 1 · read the symptom and the code before you touch anything
$ curl -i -X PATCH localhost:8080/api/orders/1/status \ -H 'Content-Type: application/json' -d '{"status":"shipped"}' HTTP/1.1 500 {"timestamp":"...","status":500,"error":"Internal Server Error"} # 服务端日志: java.lang.IllegalArgumentException: No enum constant com.techflow.orders.model.OrderStatus.shipped at java.base/java.lang.Enum.valueOf(Enum.java:293) at com.techflow.orders.model.OrderStatus.valueOf(OrderStatus.java:3) at c.t.orders.controller.OrderController.updateOrderStatus(OrderController.java:71) # mvn test:Tests run: 5, Failures: 0 ← 测试全过$ curl -i -X PATCH localhost:8080/api/orders/1/status \ -H 'Content-Type: application/json' -d '{"status":"shipped"}' HTTP/1.1 500 {"timestamp":"...","status":500,"error":"Internal Server Error"} # Server log: java.lang.IllegalArgumentException: No enum constant com.techflow.orders.model.OrderStatus.shipped at java.base/java.lang.Enum.valueOf(Enum.java:293) at com.techflow.orders.model.OrderStatus.valueOf(OrderStatus.java:3) at c.t.orders.controller.OrderController.updateOrderStatus(OrderController.java:71) # mvn test: Tests run: 5, Failures: 0 ← every test passes
JavaOrderController.java示意Illustrative
1@PatchMapping("/api/orders/{id}/status")
2public ResponseEntity<Order> updateOrderStatus(
3 @PathVariable Long id,
4 @RequestBody Map<String, String> statusUpdate) {
5 OrderStatus status = OrderStatus.valueOf(statusUpdate.get("status"));
6 return ResponseEntity.ok(orderService.updateOrderStatus(id, status));
7}
第 2 步 · 这是什么类型的错误Step 2 · what kind of error is this