![]()
チュートリアル
https://zenn.dev/hsaki/books/golang-graphql/viewer/tutorial
既存環境削除
% brew remove go # GOROOT設定されているか確認 $ echo $GOROOT # 設定されていたらディレクトリ削除、GOROOT設定されていない場合は不要 $ rm -rf $GOROOT # GOPATH設定されているか確認 $ echo $GOPATH # 設定されていたらディレクトリ削除、GOPATH設定されていない場合は不要 $ rm -rf $GOPATH 環境変数削除 # GOROOT,GOPATHの設定箇所削除 $ vi ~/.zshrc % brew uninstall goenv
$ brew install --HEAD goenv % goenv -v goenv 2.0.6
$ brew update && brew upgrade goenv $ cd $GOENV_ROOT $ git pull origin master インストールできるバージョン確認 $ goenv install -l バージョンを指定してインストール $ goenv install 1.18
$ goenv global 1.18.10 goenv2系の場合 $ vi ~/.zshrc 以下を追記 export GOENV_ROOT="$HOME/.goenv" export PATH="$GOENV_ROOT/bin:$PATH" eval "$(goenv init -)" export PATH="$GOROOT/bin:$PATH" export PATH="$PATH:$GOPATH/bin" $ source ~/.zshrc
% cd /Users/kanehiroyuu/Documents/develop.nosync/study-graphql % go install github.com/99designs/gqlgen@latest % gqlgen version v0.17.30 % go mod init my_gql_server go: /Users/kanehiroyuu/Documents/develop.nosync/study-graphql/go.mod already exists % go get -u github.com/99designs/gqlgen サンプルアプリ作成 % gqlgen init % go mod tidy
Query
query {
todos {
id
text
done
user {
name
}
}
}
Response
{
"data": {
"todos": [
{
"id": "TODO-1",
"text": "My Todo 1",
"done": true,
"user": {
"name": "hsaki"
}
},
{
"id": "TODO-2",
"text": "My Todo 2",
"done": false,
"user": {
"name": "hsaki"
}
}
]
}
}
参考になった
・Interfaceはメソッドの塊です。
・Interfaceが期待するメソッド(例ではFuncA,FuncB)をすべて満たした変数には、自動的にInterfaceが実装されます。
・Interfaceを満たした変数はInterfaceへ代入することができます。https://cloudsmith.co.jp/blog/backend/go/2021/08/1847845.html
type Hoge interface {
FuncA()
FuncB()
}
type Foo struct {}
func (f *Foo) FuncA() {}
func (f *Foo) FuncB() {}
func main() {
var hoge Hoge
hoge = Foo{..} // HogeインターフェースにFoo構造体を代入できる
}
https://github.com/saki-engineering/graphql-sample/blob/main/graph/services/users.go
package services
import (
"context"
"github.com/saki-engineering/graphql-sample/graph/db"
"github.com/saki-engineering/graphql-sample/graph/model"
"github.com/volatiletech/sqlboiler/v4/boil"
"github.com/volatiletech/sqlboiler/v4/queries/qm"
)
type userService struct {
exec boil.ContextExecutor
}
func convertUser(user *db.User) *model.User {
return &model.User{
ID: user.ID,
Name: user.Name,
}
}
func convertUserSlice(users db.UserSlice) []*model.User {
result := make([]*model.User, 0, len(users))
for _, user := range users {
result = append(result, convertUser(user))
}
return result
}
func (u *userService) GetUserByID(ctx context.Context, id string) (*model.User, error) {
user, err := db.FindUser(ctx, u.exec, id,
db.UserTableColumns.ID, db.UserTableColumns.Name,
)
if err != nil {
return nil, err
}
return convertUser(user), nil
}
func (u *userService) GetUserByName(ctx context.Context, name string) (*model.User, error) {
user, err := db.Users(
qm.Select(db.UserTableColumns.ID, db.UserTableColumns.Name),
db.UserWhere.Name.EQ(name),
// qm.Where("name = ?", name),
).One(ctx, u.exec)
if err != nil {
return nil, err
}
return convertUser(user), nil
}
func (u *userService) ListUsersByID(ctx context.Context, IDs []string) ([]*model.User, error) {
users, err := db.Users(
qm.Select(db.UserTableColumns.ID, db.UserTableColumns.Name),
db.UserWhere.ID.IN(IDs),
).All(ctx, u.exec)
if err != nil {
return nil, err
}
return convertUserSlice(users), nil
}
https://github.com/saki-engineering/graphql-sample/blob/main/graph/services/service.go
package services
import (
"context"
"github.com/saki-engineering/graphql-sample/graph/model"
"github.com/volatiletech/sqlboiler/v4/boil"
)
//go:generate mockgen -source=$GOFILE -package=$GOPACKAGE -destination=../../mock/$GOPACKAGE/service_mock.go
type Services interface {
UserService
RepoService
IssueService
PullRequestService
ProjectService
ProjectItemService
}
type UserService interface {
GetUserByID(ctx context.Context, id string) (*model.User, error)
GetUserByName(ctx context.Context, name string) (*model.User, error)
ListUsersByID(ctx context.Context, IDs []string) ([]*model.User, error)
}
type RepoService interface {
GetRepoByID(ctx context.Context, id string) (*model.Repository, error)
GetRepoByFullName(ctx context.Context, owner, name string) (*model.Repository, error)
}
type IssueService interface {
GetIssueByID(ctx context.Context, id string) (*model.Issue, error)
GetIssueByRepoAndNumber(ctx context.Context, repoID string, number int) (*model.Issue, error)
ListIssueInRepository(ctx context.Context, repoID string, after *string, before *string, first *int, last *int) (*model.IssueConnection, error)
}
type PullRequestService interface {
GetPullRequestByID(ctx context.Context, id string) (*model.PullRequest, error)
GetPullRequestByRepoAndNumber(ctx context.Context, repoID string, number int) (*model.PullRequest, error)
ListPullRequestInRepository(ctx context.Context, repoID string, after *string, before *string, first *int, last *int) (*model.PullRequestConnection, error)
}
type ProjectService interface {
GetProjectByID(ctx context.Context, id string) (*model.ProjectV2, error)
GetProjectByOwnerAndNumber(ctx context.Context, ownerID string, number int) (*model.ProjectV2, error)
ListProjectByOwner(ctx context.Context, ownerID string, after *string, before *string, first *int, last *int) (*model.ProjectV2Connection, error)
}
type ProjectItemService interface {
GetProjectItemByID(ctx context.Context, id string) (*model.ProjectV2Item, error)
ListProjectItemOwnedByProject(ctx context.Context, projectID string, after *string, before *string, first *int, last *int) (*model.ProjectV2ItemConnection, error)
ListProjectItemOwnedByIssue(ctx context.Context, issueID string, after *string, before *string, first *int, last *int) (*model.ProjectV2ItemConnection, error)
ListProjectItemOwnedByPullRequest(ctx context.Context, pullRequestID string, after *string, before *string, first *int, last *int) (*model.ProjectV2ItemConnection, error)
AddIssueInProjectV2(ctx context.Context, projectID, issueID string) (*model.ProjectV2Item, error)
AddPullRequestInProjectV2(ctx context.Context, projectID, pullRequestID string) (*model.ProjectV2Item, error)
}
type services struct {
*userService
*repoService
*issueService
*pullRequestService
*projectService
*projectItemService
}
func New(exec boil.ContextExecutor) Services {
return &services{
userService: &userService{exec: exec},
repoService: &repoService{exec: exec},
issueService: &issueService{exec: exec},
pullRequestService: &pullRequestService{exec: exec},
projectService: &projectService{exec: exec},
projectItemService: &projectItemService{exec: exec},
}
}





