NickNameããã«ã¡ã¯ïŒããã°ã©ããŒã§ãã€ã¯ããµãŒãã¹ã¢ãŒããã¯ãã£ã䜿çšããŠããå Žåã¯ããµãŒãã¹Aãšæ°ãããŸã äžæãªãµãŒãã¹Bãšã®çžäºäœçšãæ§æããå¿ èŠããããšæ³åããŠãã ãããæåã«äœãããŸããïŒ
ããŸããŸãªäŒæ¥ã®100人ã®ããã°ã©ããŒã«ãã®è³ªåããããšã100ã®ç°ãªãåçãåŸãããå¯èœæ§ããããŸãã誰ããå¥çŽãã¹ã¯ãã¬ãŒã§èª¬æããgRPCã®èª°ãããå¥çŽã説æããã«åã«ã¯ã©ã€ã¢ã³ãããµãŒãã¹ã«èªå°ããŸãããããŠèª°ããJSONãgoogleokã«ä¿åããããšãããããŸãïŒDãã»ãšãã©ã®äŒæ¥ã¯ãããã€ãã®æŽå²çèŠå ãèœåããã¯ãããžãŒã¹ã¿ãã¯ãªã©ã«åºã¥ããŠããµãŒãã¹éçžäºäœçšã«å¯Ÿããç¬èªã®ã¢ãããŒããéçºããŠããŸãã Delivery Clubã®ãµãŒãã¹ãã©ã®ããã«çžäºã«éä¿¡ãããªããã®ãããªéžæãããã®ããã話ãããããšæããŸãããããŠæãéèŠãªããšã¯ãæéã®çµéãšãšãã«ããã¥ã¡ã³ãã®é¢é£æ§ãã©ã®ããã«ç¢ºä¿ãããã§ããããããã®ã³ãŒãããããŸãïŒ
ãŸãäŒã£ããïŒç§ã®ååã¯ã»ã«ã²ã€ã»ãããã§ããã¢ããªãšããªããªãŒã¯ã©ãã®ãŠã§ããµã€ãã§ã¬ã¹ãã©ã³ã®æ€çŽ¢çµæãæ åœããããŒã ã®ããŒã ãªãŒããŒã§ãããGoã®ç€Ÿå éçºã®ã«ãã®ç©æ¥µçãªã¡ã³ããŒã§ããããŸãïŒããã«ã€ããŠã¯åŸã§è©±ããŸãããä»ã¯è©±ããŸããïŒã
ããã«äºçŽããŸããäž»ã«å²ç¢ã§æžããããµãŒãã¹ã«ã€ããŠè©±ããŸããPHPãµãŒãã¹ã®ã³ãŒãçæã¯ãŸã å®è£ ããŠããŸããããç°ãªãæ¹æ³ã§ã¢ãããŒãã®åäžæ§ãå®çŸããŠããŸãã
æçµçã«ããããã£ãããšïŒ
- ãµãŒãã¹å¥çŽãææ°ã§ããããšã確èªããŠãã ãããããã«ãããæ°ãããµãŒãã¹ã®å°å ¥ãã¹ããŒãã¢ããããããŒã éã®ã³ãã¥ãã±ãŒã·ã§ã³ã容æã«ãªããŸãã
- ãµãŒãã¹éã®HTTPãä»ããçžäºäœçšã®çµ±äžãããæ¹æ³ãèããŠã¿ãŸãããïŒçŸæç¹ã§ã¯ããã¥ãŒãã€ãã³ãã¹ããªãŒãã³ã°ãä»ããçžäºäœçšã«ã€ããŠã¯èæ ®ããŸããïŒã
- ãµãŒãã¹å¥çŽãæ±ãã¢ãããŒããæšæºåããã
- ããããçš®é¡ã®åæµç¹ã®ããã¯ãæ¢ããªãããã«ãå¥çŽã®åäžã®ãªããžããªã䜿çšããŸãã
- çæ³çã«ã¯ãããŸããŸãªãã©ãããã©ãŒã çšã®ã¯ã©ã€ã¢ã³ããçæããŸãã
äžèšã®ãã¹ãŠãããProtobufã¯å¥çŽã説æããããã®çµ±äžãããæ¹æ³ãšããŠæãæµ®ãã³ãŸããåªããããŒã«ããããããŸããŸãªãã©ãããã©ãŒã çšã®ã¯ã©ã€ã¢ã³ããçæã§ããŸãïŒç¬¬5é ïŒãããããæãããªæ¬ ç¹ããããŸããå€ãã®å ŽåãgRPCã¯æ°ããæªç¥ã®ãã®ã§ãããããã«ããå®è£ ãéåžžã«è€éã«ãªããŸãããã1ã€ã®éèŠãªèŠçŽ ã¯ãäŒç€Ÿãé·ãéã仿§åªå ãã¢ãããŒããæ¡çšããŠããããã¹ãŠã®ãµãŒãã¹ã®ããã¥ã¡ã³ããã¹ã¯ãã¬ãŒãŸãã¯RAMLã®èª¬æã®åœ¢åŒã§ãã§ã«ååšããŠããããšã§ãã
ãŽãŒã¹ã¯ãã¬ãŒ
å¶ç¶ã«ããåæã«ãç§ãã¡ã¯äŒç€Ÿã§Goãæ¡çšãå§ããŸããããããã£ãŠãæ¬¡ã«æ€èšããåè£ã¯go-swaggerã§ãããããã¯ãswagger仿§ããã¯ã©ã€ã¢ã³ããšãµãŒããŒã³ãŒããçæã§ããããŒã«ã§ããæãããªæ¬ ç¹ã¯ãGoã®ã³ãŒãããçæããªãããšã§ããå®éãgoshã³ãŒãçæã䜿çšããgo-swaggerã䜿çšãããšãã³ãã¬ãŒããæè»ã«æäœã§ãããããçè«çã«ã¯PHPã³ãŒãã®çæã«äœ¿çšã§ããŸããããŸã 詊ããŠããŸããã
Go-swaggerã¯ããã©ã³ã¹ããŒãã¬ã€ã€ãŒã®çæã ãã§ã¯ãããŸãããå®éãããã¯ã¢ããªã±ãŒã·ã§ã³ã¹ã±ã«ãã³ãçæããŸããããã§ãDCã®éçºæåã«ã€ããŠå°ãè§ŠããŠãããããšæããŸããå éšãœãŒã¹ããããŸããã€ãŸããã©ã®ããŒã ã®ã©ã®éçºè ããç§ãã¡ãæã£ãŠãããã¹ãŠã®ãµãŒãã¹ãžã®ãã«ãªã¯ãšã¹ããäœæã§ããŸãããã®ãããªã¹ããŒã ãæ©èœããããã«ãéçºã«ãããã¢ãããŒããæšæºåããããšããŠããŸããäžè¬çãªçšèªããã®ã³ã°ãã¡ããªãã¯ãäŸåé¢ä¿ã®æäœããããŠãã¡ãããããžã§ã¯ãæ§é ãžã®åäžã®ã¢ãããŒãã䜿çšããŸãã
ãã®ããã«ãgo-swaggerãå®è£ ããããšã«ãããGoã§ãµãŒãã¹ãéçºããããã®æšæºãå°å ¥ããŠããŸããããã¯ãåœåã¯äºæããŠããªãã£ãç®æšã«åãããã1ã€ã®ã¹ãããã§ãããéçºå šè¬ã«ãšã£ãŠéèŠã§ãã
æåã®ã¹ããã
ã ãããè¡ã-éæ©ã¯ãç§ãã¡ã®ã»ãšãã©ã«ããŒããããšãã§ããããã«æãããè峿·±ãåè£ã§ããããšã倿ã
泚ïŒãã¹ãŠã®æŽãªãã³ãŒãã¯ããŒãžã§ã³0.24.0ã«é¢é£ãããã€ã³ã¹ããŒã«æé ã¯ã§èŠã€ããããšãã§ããäŸã§ç§ãã¡ã®ãªããžããªãããã³å ¬åŒãµã€ãã§ã¯ãçŸåšã®ããŒãžã§ã³ã®ã€ã³ã¹ããŒã«æé ã«ã€ããŠèª¬æããŠããŸãã圌ã«äœãã§ãããèŠãŠã¿ãŸããããã¹ã¯ã¬ãŒã¹ããã¯ãåãããµãŒãã¹ãçæããŸãããïŒ
> goswagger generate server \
--with-context -f ./swagger-api/swagger.yml \
--name example1
以äžãååŸããŸããïŒ
Makefileãšgo.modç§ã¯ãã§ã«èªåã§äœæããŸããã
å®éãswaggerã§èª¬æãããŠãããªã¯ãšã¹ããåŠçãããµãŒãã¹ã«ãªããŸããã
> go run cmd/example1-server/main.go
2020/02/17 11:04:24 Serving example service at http://127.0.0.1:54586
> curl http://localhost:54586/hello -i
HTTP/1.1 501 Not Implemented
Content-Type: application/json
Date: Sat, 15 Feb 2020 18:14:59 GMT
Content-Length: 58
Connection: close
"operation hello HelloWorld has not yet been implemented"
ã¹ããã2ããã³ãã¬ãŒãã£ã³ã°ãçè§£ãã
æããã«ãç§ãã¡ãçæããã³ãŒãã¯ãç§ãã¡ãéçšäžã«èŠãããã®ãšã¯ããé¢ããŠããŸãã
ã¢ããªã±ãŒã·ã§ã³ã®æ§é ã«æ±ãããã®ïŒ
- ã¢ããªã±ãŒã·ã§ã³ãæ§æã§ããŸããããŒã¿ããŒã¹ã«æ¥ç¶ããããã®èšå®ã転éããããHTTPæ¥ç¶ã®ããŒããæå®ãããã§ããŸãã
- ã¢ããªã±ãŒã·ã§ã³ã®ç¶æ ãããŒã¿ããŒã¹æ¥ç¶ãªã©ãæ ŒçŽããã¢ããªã±ãŒã·ã§ã³ãªããžã§ã¯ããéžæããŸãã
- ã¢ããªã±ãŒã·ã§ã³ã®ãã³ãã©ãŒé¢æ°ãäœæããŸããããã«ãããã³ãŒãã®äœæ¥ãç°¡çŽ åãããŸãã
- ã¡ã€ã³ãã¡ã€ã«ã®äŸåé¢ä¿ãåæåããŸãïŒãã®äŸã§ã¯ãããã¯çºçããŸããããããã§ãå¿ èŠã§ãã
æ°ããåé¡ã解決ããããã«ãããã€ãã®ãã³ãã¬ãŒãããªãŒããŒã©ã€ãã§ããŸãããããè¡ãã«ã¯ãç§ãè¡ã£ãããã«ïŒGithubïŒã次ã®ãã¡ã€ã«ã«ã€ããŠèª¬æããŸãããµãŒãã¹ãçæããããã®
ãã³ãã¬ãŒããã¡ã€ã«ïŒ
`*.gotmpl`ïŒãšæ§æçšã®ãã¡ã€ã«ïŒïŒã説æããå¿
èŠããã`*.yml`ãŸãã
次ã«ãç§ãäœæãããã³ãã¬ãŒããé çªã«åæããŸãããŽãŒéæ©ããã¥ã¡ã³ãã¯ããªãããšãã°ã詳述ãããŠããã®ã§ãç§ã¯ã圌ããšååã«æ·±ãæœããŸããããã«ããèšå®ãã¡ã€ã«ã®èšè¿°ããGo-templatingã䜿çšãããŠããããšã«æ³šæããŠãã ãããããã«ã€ããŠæ¢ã«çµéšãããå ŽåããŸãã¯HELMæ§æã«ã€ããŠèª¬æããå¿ èŠãããå Žåã¯ããããçè§£ããã®ã¯é£ãããããŸããã
ã¢ããªã±ãŒã·ã§ã³ã®æ§æ
config.gotmplã«ã¯ã1ã€ã®ãã©ã¡ãŒã¿ãŒïŒã¢ããªã±ãŒã·ã§ã³ãçä¿¡HTTPèŠæ±ããªãã¹ã³ããããŒãïŒãæã€åçŽãªæ§é ãå«ãŸããŠããŸãããŸã
InitConfigãç°å¢å€æ°ãèªã¿åãããã®æ§é ãåãã颿°ãäœæããŸãããmain.goããåŒã³åºãã®ã§InitConfigããããªãã¯é¢æ°ã«ããŸããã
package config
import (
"github.com/pkg/errors"
"github.com/vrischmann/envconfig"
)
// Config struct
type Config struct {
HTTPBindPort int `envconfig:"default=8001"`
}
// InitConfig func
func InitConfig(prefix string) (*Config, error) {
config := &Config{}
if err := envconfig.InitWithPrefix(config, prefix); err != nil {
return nil, errors.Wrap(err, "init config failed")
}
return config, nil
}
ãã®ãã³ãã¬ãŒããã³ãŒãã®çææã«äœ¿çšããã«ã¯ãYMLæ§æã§ãã³ãã¬ãŒããæå®ããå¿ èŠããããŸãã
layout:
application:
- name: cfgPackage
source: serverConfig
target: "./internal/config/"
file_name: "config.go"
skip_exists: false
ãã©ã¡ãŒã¿ã«ã€ããŠå°ã説æããŸãã
name-çŽç²ã«æçãªæ©èœããããçæã«ã¯åœ±é¿ããŸãããsource-å®éã«ã¯ãcamelCaseã®ãã³ãã¬ãŒããã¡ã€ã«ãžã®ãã¹ãã€ãŸã serverConfigã¯./server/config.gotmplãšåçã§ããtarget-çæãããã³ãŒããä¿åããããã£ã¬ã¯ããªãããã§ã¯ããã³ãã¬ãŒãã䜿çšããŠãã¹ãåçã«çæã§ããŸãïŒäŸïŒãfile_name-çæããããã¡ã€ã«ã®ååãããã§ã¯ãã³ãã¬ãŒãã䜿çšããããšãã§ããŸããskip_exists-ãã¡ã€ã«ã1åã ãçæãããæ¢åã®ãã¡ã€ã«ãäžæžãããªãããšã瀺ããŸããæ§æãã¡ã€ã«ã¯ã¢ããªã±ãŒã·ã§ã³ã®æé·ã«å¿ããŠå€æŽãããçæãããã³ãŒãã«äŸåããã¹ãã§ã¯ãªããããããã¯ç§ãã¡ã«ãšã£ãŠéèŠã§ãã
ã³ãŒãçææ§æã§ã¯ããªãŒããŒã©ã€ããããã¡ã€ã«ã ãã§ãªãããã¹ãŠã®ãã¡ã€ã«ãæå®ããå¿ èŠããããŸãã倿Žããªããã¡ã€ã«ã®å Žåãããšãã°ãããã§
sourceææããæå³ã®ç¯å²å
ã§ïŒãã¡ãªã¿ã«ããªãªãžãã«ã®ãã³ãã¬ãŒããã芧ã«ãªãããæ¹ã¯ãã¡ããasset:< >asset:serverConfigureapi
ã¢ããªã±ãŒã·ã§ã³ãªããžã§ã¯ããšãã³ãã©ãŒ
ç¶æ ãããŒã¿ããŒã¹æ¥ç¶ãªã©ãä¿åããããã®ã¢ããªã±ãŒã·ã§ã³ãªããžã§ã¯ãã«ã€ããŠã¯èª¬æããŸããããã¹ãŠãäœæããã°ããã®æ§æã«äŒŒãŠããŸãããããããã³ãã©ãŒã䜿çšãããšããã¹ãŠãããå°ãè峿·±ããã®ã«ãªããŸããç§ãã¡ã®äž»ãªç®æšã¯ã仿§ã«URLã远å ãããšãã«å¥ã®ãã¡ã€ã«ã«ã¹ã¿ã颿°ãäœæããããšã§ããæãéèŠãªããšã¯ããµãŒããŒããã®é¢æ°ãåŒã³åºããŠèŠæ±ãåŠçããããšã§ãã
颿°ãã³ãã¬ãŒããšã¹ã¿ãã«ã€ããŠèª¬æããŸãããã
package app
import (
api{{ pascalize .Package }} "{{.GenCommon.TargetImportPath}}/{{ .RootPackage }}/operations/{{ .Package }}"
"github.com/go-openapi/runtime/middleware"
)
func (srv *Service){{ pascalize .Name }}Handler(params api{{ pascalize .Package }}.{{ pascalize .Name }}Params{{ if .Authorized }}, principal api{{ .Package }}.{{ if not ( eq .Principal "interface{}" ) }}*{{ end }}{{ .Principal }}{{ end }}) middleware.Responder {
return middleware.NotImplemented("operation {{ .Package }} {{ pascalize .Name }} has not yet been implemented")
}
äŸã詳ããèŠãŠã¿ãŸãããã
pascalize--CamelCaseïŒä»ã®æ©èœã®èª¬æã¯ãã¡ãïŒã§äžç·ãç»ããŸãã.RootPackage-çæãããWebãµãŒããŒããã±ãŒãžã.Package-çæãããã³ãŒãå ã®ããã±ãŒãžã®ååãHTTPèŠæ±ãšå¿çã«å¿ èŠãªãã¹ãŠã®æ§é ãèšè¿°ããŸããæ§é ãããšãã°ããªã¯ãšã¹ãæ¬æã®æ§é ãã¬ã¹ãã³ã¹æ§é ãªã©ã§ãã.Name-ãã³ãã©ãŒã®ååãæå®ãããŠããå Žåã¯ã仿§ã®operationIDããååŸãããŸããoperationIDããæçœãªçµæãåŸãããã«ãåžžã«æå®ããããšããå§ãããŸãã
ãã³ãã©ãŒã®æ§æã¯æ¬¡ã®ãšããã§ãã
layout:
operations:
- name: handlerFns
source: serverHandler
target: "./internal/app"
file_name: "{{ (snakize (pascalize .Name)) }}.go"
skip_exists: true
ã芧ã®ãšããããã³ãã©ãŒã³ãŒãã¯äžæžããããïŒ
skip_exists: trueïŒããã¡ã€ã«åã¯ãã³ãã©ãŒåããçæãããŸãã
ããŠãã¹ã¿ã颿°ããããŸãããWebãµãŒããŒã¯ããããã®é¢æ°ã䜿çšããŠèŠæ±ãåŠçããå¿ èŠãããããšããŸã èªèããŠããŸãããmain.goã§ãããä¿®æ£ããŸããïŒã³ãŒãå šäœãæäŸããããã§ã¯ãããŸãããå®å šçã¯ããã«ãããŸãïŒïŒ
package main
{{ $name := .Name }}
{{ $operations := .Operations }}
import (
"fmt"
"log"
"github.com/delivery-club/go-swagger-example/{{ dasherize .Name }}/internal/generated/restapi"
"github.com/delivery-club/go-swagger-example/{{ dasherize .Name }}/internal/generated/restapi/operations"
{{range $index, $op := .Operations}}
{{ $found := false }}
{{ range $i, $sop := $operations }}
{{ if and (gt $i $index ) (eq $op.Package $sop.Package)}}
{{ $found = true }}
{{end}}
{{end}}
{{ if not $found }}
api{{ pascalize $op.Package }} "{{$op.GenCommon.TargetImportPath}}/{{ $op.RootPackage }}/operations/{{ $op.Package }}"
{{end}}
{{end}}
"github.com/go-openapi/loads"
"github.com/vrischmann/envconfig"
"github.com/delivery-club/go-swagger-example/{{ dasherize .Name }}/internal/app"
)
func main() {
...
api := operations.New{{ pascalize .Name }}API(swaggerSpec)
{{range .Operations}}
api.{{ pascalize .Package }}{{ pascalize .Name }}Handler = api{{ pascalize .Package }}.{{ pascalize .Name }}HandlerFunc(srv.{{ pascalize .Name }}Handler)
{{- end}}
...
}
ã€ã³ããŒãã®ã³ãŒãã¯è€éã«èŠããŸãããå®éã«ã¯Go-templatingãšgo-swaggerãªããžããªããã®æ§é ã«ãããŸããããŸãã颿°ã§
mainã¯ãçæããã颿°ããã³ãã©ãŒã«å²ãåœãŠãã ãã§ãã
æ§æã瀺ãã³ãŒããçæããå¿ èŠããããŸãã
> goswagger generate server \
-f ./swagger-api/swagger.yml \
-t ./internal/generated -C ./swagger-templates/default-server.yml \
--template-dir ./swagger-templates/templates \
--name example2
æçµçµæã¯ããªããžããªã§è¡šç€ºã§ããŸãã
ç§ãã¡ãåŸããã®ïŒ
- ã¢ããªã±ãŒã·ã§ã³ãæ§æãããã³å¿ èŠãªãã®ã«æ§é ã䜿çšã§ããŸããæãéèŠãªããšã¯ãçæãããã³ãŒãã«åã蟌ãã®ãããªãç°¡åãªããšã§ãã
- åã ã®ãã¡ã€ã«ã®ååã«è³ããŸã§ããããžã§ã¯ãã®æ§é ãæè»ã«ç®¡çã§ããŸãã
- ãã³ãã¬ãŒãã£ã³ã°ã¯è€éã«èŠããæ £ãããŸã§ã«æéãããããŸãããå šäœãšããŠã¯éåžžã«åŒ·åãªããŒã«ã§ãã
ã¹ããã3ãã¯ã©ã€ã¢ã³ãã®çæ
Go-swaggerã䜿çšãããšãä»ã®GoãµãŒãã¹ã䜿çšã§ãããµãŒãã¹ã®ã¯ã©ã€ã¢ã³ãããã±ãŒãžãçæããããšãã§ããŸããããã§ã¯ãã³ãŒãçæã«ã€ããŠè©³ããã¯èª¬æããŸãããã¢ãããŒãã¯ããµãŒããŒåŽã®ã³ãŒããçæããå ŽåãšãŸã£ããåãã§ãã
Goãããžã§ã¯ãã®å Žåããããªãã¯ããã±ãŒãžãã«å ¥ããã®ãéäŸ
./pkgã§ããåãããšãè¡ããŸãããµãŒãã¹ã®ã¯ã©ã€ã¢ã³ããpkgã«å
¥ããæ¬¡ã®ããã«ã³ãŒãèªäœãçæããŸãã
> goswagger generate client -f ./swagger-api/swagger.yml -t ./pkg/example3
çæãããã³ãŒãã®äŸã¯ããã«ãããŸãã
ããã§ããµãŒãã¹ã®ãã¹ãŠã®å©çšè ã¯ãããšãã°ã¿ã°ã䜿çšããŠããã®ã¯ã©ã€ã¢ã³ããèªåã§ã€ã³ããŒãã§ããŸãïŒç§ã®äŸã§ã¯ãã¿ã°ã¯ã«ãªããŸã
example3/pkg/example3/v0.0.1ïŒã
ã¯ã©ã€ã¢ã³ããã³ãã¬ãŒãã¯ãããšãã°ã
open tracing idã³ã³ããã¹ãããããããŒãžã®ãããŒã«ã«ã¹ã¿ãã€ãºã§ããŸãã
çµè«
åœç¶ãå éšå®è£ ã¯ãäž»ã«å éšããã±ãŒãžã®äœ¿çšãšCIãžã®ã¢ãããŒãïŒããŸããŸãªãã¹ããšãªã³ã¿ãŒã®å®è¡ïŒãåå ã§ãããã«ç€ºãããŠããã³ãŒããšã¯ç°ãªããŸããç®±ããåºããŠçæãããã³ãŒãã§ã¯ãæè¡ã¡ããªãã¯ã®åéãæ§æã®æäœãããã³ãã®ã³ã°ãæ§æãããŠããŸãããã¹ãŠã®äžè¬çãªããŒã«ãæšæºåããŸããããã®ãããéçºå šè¬ãç¹ã«æ°ãããµãŒãã¹ã®ãªãªãŒã¹ãç°¡çŽ åãã補åã«å±éããåã«ãµãŒãã¹ãã§ãã¯ãªã¹ããããè¿ éã«ééã§ããããã«ããŸããã
æåã®ç®æšãéæãããã©ããã確èªããŸãããã
- ãµãŒãã¹ã«ã€ããŠèª¬æãããŠããå¥çŽã®é¢é£æ§ã確èªããŸããããã«ãããæ°ãããµãŒãã¹ã®å°å ¥ãå éãããããŒã éã®ã³ãã¥ãã±ãŒã·ã§ã³ãç°¡çŽ åãããŸã-ã¯ãã
- HTTP ( event streaming) â .
- , .. Inner Source â .
- , â ( â Bitbucket).
- , â ( , , ).
- Go â ( ).
æ³šææ·±ãèªè ã¯ãããããã§ã«è³ªåãããŠããã§ãããïŒãã³ãã¬ãŒããã¡ã€ã«ã¯ã©ã®ããã«ç§ãã¡ã®ãããžã§ã¯ãã«å ¥ãã®ã§ããïŒçŸåšãåãããžã§ã¯ãã«ããããä¿åããŠããŸããããã«ãããæ¥åžžã®äœæ¥ãç°¡çŽ åãããç¹å®ã®ãããžã§ã¯ãã«åãããŠäœããã«ã¹ã¿ãã€ãºã§ããŸããããããã³ã€ã³ã«ã¯å¥ã®åŽé¢ããããŸããäž»ã«CIã«é¢é£ããããã³ãã¬ãŒãã®éäžæŽæ°ãšæ°æ©èœã®æäŸã®ããã®ã¡ã«ããºã ããããŸããã
PSãã®è³æãæ°ã«å ¥ã£ãå Žåã¯ãå°æ¥ããµãŒãã¹ã®æšæºã¢ãŒããã¯ãã£ã«é¢ããèšäºãäœæããGoã§ãµãŒãã¹ãéçºãããšãã«äœ¿çšããååã«ã€ããŠèª¬æããŸãã