洗濯機の給水ホースを取り付けなおしてもらってから、洗濯物の乾きがよくないな、洗濯物を詰め込みすぎてはいないと思うけどそれでも乾きが悪いな……と思っていたけど、原因は別のところにあった。漏水が怖いのですすぎ洗いが終わった段階で蛇口の栓を締めるようにしていたけど、それがよくなかった。乾燥中も蛇口は開けておかないといけない。
● 蛇口が開いていないときも乾燥できずに終わります。(水冷除湿式です。蛇口は必ず開いてください。蛇口を開かずに運転しても、お知らせしませんのでご注意ください)
洗濯機の給水ホースを取り付けなおしてもらってから、洗濯物の乾きがよくないな、洗濯物を詰め込みすぎてはいないと思うけどそれでも乾きが悪いな……と思っていたけど、原因は別のところにあった。漏水が怖いのですすぎ洗いが終わった段階で蛇口の栓を締めるようにしていたけど、それがよくなかった。乾燥中も蛇口は開けておかないといけない。
● 蛇口が開いていないときも乾燥できずに終わります。(水冷除湿式です。蛇口は必ず開いてください。蛇口を開かずに運転しても、お知らせしませんのでご注意ください)
前日に飲酒しまっくてクタクタだけど8時に目が覚めて、フィットボクシングをやった後、夕方までの予定を考える。
やりました #NintendoSwitch pic.twitter.com/tj3FyQg6tZ
— うたがわきき (@utgwkk) 2022年4月23日
そういえば無印良品週間が始まったし、せっかくなので山科にあるという巨大な無印に行ってみよう、ということで決まった。
駅に着いたのでATMを探してショッピングセンターに入って、適当なスーパーを通過していると思ったら実はそこが無印だった。お金をおろしてからラーメンを食べようと思っていたけど、無印はもう始まっていたのだった。早速の洗礼である。
昼食を済ませてから、巨大な無印の一部に取り込まれることを決める。まず店舗が広い。歩き疲れてしまう。ベッドやソファに座れなかったらただちに終わっていたと思う。
ちょっと旅行する予定があるので、小さなスキンケアセットとポーチを買った。そこからは永遠とも思われるウィンドウショッピングをする。
地下のスーパーコーナーも見て回ってみたところ、なんと店内で寿司を食べられる。無印と寿司、近いようで遠い概念同士が邂逅したのであった。ビールコーナーがやけに充実していて、家の近くにも欲しくなる。
山科の巨大無印良品にはこの世が詰まっている。間違いなくそう思った。今はネットストアを物色している。
おかげで数がすごいことになっています。
平日に1.5Lペットボトルを1.5本弱ペースで飲むので、2週間で2箱 (12本) がいちばん近いか? 定期おトク便の周期を合わせるまでが大変で、家に大量のコーラがある暮らしが続いていた。今はちょっと足りないかもしれない。
五月雨を utf8mb4
— うたがわきき (@utgwkk) 2022年4月19日
複数のIDを指定してデータを一括で取得したい場合があって、手作りした。ナイーブにはこういう感じでいける。N+1クエリになるのでもうちょっとうまくやる必要がありそう。
import graphene class Query(ObjectType): # 中略 nodes = graphene.Field( graphene.NonNull(graphene.List(relay.Node)), ids=graphene.List( graphene.NonNull(graphene.ID), required=True, description="The IDs of the object", ), ) def resolve_nodes(root, info, **args): ids = args["ids"] return [graphene.relay.Node.node_resolver(None, root, info, id) for id in ids]
こういう実装をしたら以下のようなGraphQLスキーマになる。
type Query { # 中略 nodes( """The IDs of the object""" ids: [ID!]! ): [Node]! }
Go言語でGraphQL APIを叩くクライアントを書くことがあって、クエリをベタ書きするのはともかく返り値にマッピングされるようなstructの型を用意するのが面倒すぎる。正常系だけならそれでもまだなんとかなるかもしれないけど、異常系のことも考えて書く……となると気が遠くなる。
なんとかならないかと思って探していたら表題のクライアントを見つけた。GitHub - shurcooL/graphql: Package graphql provides a GraphQL client implementation. をフォークして機能追加したライブラリらしい。
以下のようなGraphQLスキーマがあるとする。実際のスキーマからはだいぶ端折っている。
type Artwork implements Node { id: ID! title: String! caption: String! nsfw: Boolean! topIllust: Illust } type Illust implements Node { """The ID of the object.""" id: ID! thumbnailUrl: String! }
たとえば以下のようなGraphQLクエリを発行したいとする。
query artworkInfoQuery($id: ID!){ node(id: $id) { ... on Artwork { title caption nsfw topIllust { thumbnailUrl } } } }
以下のような無名structを作ってあげたら、変数も渡しつつリクエストできる。inline fragmentもシャッと書ける。これだけでGraphQLクエリを手書きする手間、レスポンスのJSONに合わせたstructを作る手間、異常系をハンドリングする手間が1つにまとまった。
graphqlClient := graphql.NewClient(graphqlAPIEndpoint, nil) var artworkInfoQuery struct { Node struct { Artwork struct { Title graphql.String Caption graphql.String Nsfw graphql.Boolean TopIllust struct { ThumbnailUrl graphql.String } } `graphql:"... on Artwork"` } `graphql:"node(id: $id)"` } err = graphqlClient.Query(context.Background(), &artworkInfoQuery, map[string]interface{}{ "id": graphql.ID(artworkID), }) if err != nil { log.Print(err) return }
ちょっとGraphQL APIを叩いてなんかやりたい、ぐらいのときには愛用することになりそう。