0
文字列からgithubv4.Dateに変換する
2022-10-29

GoでGitHub CLIの拡張を作っている際

GraphQLでProjectV2のデータ更新しようとしていた

しかし、ProjectV2の日付フィールドを更新しようといろいろやったが全然うまくいかずかなり時間を溶かしてしまったので残しておく

GraphQLのmutationとパラメータを指定する部分

一部抜き出した(このコードじゃ動かない)

	var mutation struct {
		UpdateProjectV2ItemFieldValue struct {
			ClientMutationID string
		} `graphql:"updateProjectV2ItemFieldValue(input: {projectId: $projectId itemId: $itemId fieldId: $fieldId value: {date: $value}})"`
	}
	dateString := "2022-10-01"
	variables := map[string]interface{}{
		"projectId": graphql.ID(projectId),
		"itemId":    graphql.ID(itemId),
		"fieldId":   graphql.ID(fieldId),
		"value":     dateString,
	}
	err = gqlclient.Mutate("Assign", &mutation, variables)

DATE型のフィールド

GitHubのドキュメント

スカラー - GitHub Docs

上記のように文字列で投げたら怒られる

Message: Type mismatch on variable $value and argument date (ID! / Date), Locations: [{Line:1 Column:168}]

$valueはDate型が必要ですよと

githubv4/scalar.go at master · shurcooL/githubv4

githubv4.Dateの定義を見に行くと

Date struct { time.Time }

となっている

型キャスト

ということで、普通にキャストすればよいかと思ったがだめだった

	var mutation struct {
		UpdateProjectV2ItemFieldValue struct {
			ClientMutationID string
		} `graphql:"updateProjectV2ItemFieldValue(input: {projectId: $projectId itemId: $itemId fieldId: $fieldId value: {date: $value}})"`
	}
	dateString := "2022-09-01T00:00:00Z"
	t, _ := time.Parse("2006-01-02T15:04:05Z", dateString)
	variables := map[string]interface{}{
		"projectId": graphql.ID(projectId),
		"itemId":    graphql.ID(itemId),
		"fieldId":   graphql.ID(fieldId),
		"value":     githubv4.Date(t),
	}
	err = gqlclient.Mutate("Assign", &mutation, variables)

型エラーで怒られる

cannot convert t (variable of type time.Time) to type githubv4.Date

動くコード

結局下記のようなコードで動かした

package main

import (
	"encoding/json"
	"fmt"
	"github.com/cli/go-gh"
	graphql "github.com/cli/shurcooL-graphql"
	"github.com/shurcool/githubv4"
	"log"
)

type NamedDateValue struct {
	Date githubv4.Date `json:"date,omitempty"`
}

func main() {
	projectId := "適当なIDを入れる"
	itemId := "適当なIDを入れる"
	fieldId := "適当なIDを入れる"

	gqlclient, err := gh.GQLClient(nil)
	if err != nil {
		log.Fatal(err)
	}

	var mutation struct {
		UpdateProjectV2ItemFieldValue struct {
			ClientMutationID string
		} `graphql:"updateProjectV2ItemFieldValue(input: {projectId: $projectId itemId: $itemId fieldId: $fieldId value: {date: $value}})"`
	}

	b := []byte(`{"date":"2022-09-01T00:00:00Z"}`)
	var v NamedDateValue
	if err := json.Unmarshal(b, &v); err != nil {
		panic(err)
	}

	variables := map[string]interface{}{
		"projectId": graphql.ID(projectId),
		"itemId":    graphql.ID(itemId),
		"fieldId":   graphql.ID(fieldId),
		"value":     v.Date,
	}

	err = gqlclient.Mutate("Assign", &mutation, variables)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(mutation)
}

こんな感じ

NamedDateValueという型を定義してjson.Unmarshalで変換する

この構造体はgithubv4.Date型のDateフィールドを持っている

GraphQLのパラメータを渡す際にv.Dateで型を合うようにした

もっとよい方法がありそうだが今の自分の力ではこれが限界だった

ただこれを解決しないと進めなかったのでいろいろ調べて勉強にはなった

ということでjson.Unmarshalすごい

0

Profile

swfz
swfz
日々学んだことを残していく
Today I Learned
コード片置き場

Account

RSS

Powered by Pixela
© 2024. swfz