# 達易技術分享交流 <img src="https://i.imgur.com/g0Qv17q.jpg" width="75%"/> # Agenda * Go - swagger * React - Hooks - ES6 * 學習資源 - Free - [保哥BLOG](https://blog.miniasp.com/) - [MDN](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript) - [Academind](https://www.youtube.com/channel/UCSJbGtTlrDami-tDGPUV9-w/playlists) - [Traversy Media](https://www.youtube.com/user/TechGuyWeb/playlists) - [GitHub: O'Reilly - Learning React](https://github.com/MoonHighway/learning-react) - [GitHub: Learn React Hooks](https://github.com/PacktPublishing/Learn-React-Hooks) - $$$ - [LinkedIn Learning](https://www.linkedin.com/learning/) - [Udemy](https://www.udemy.com/) ## Go - Swagger - [swaggo/swag](https://github.com/swaggo/swag) - 支援 web Frameworks - net/http - buffalo - echo - gin [swaggo/gin-swagger](https://github.com/swaggo/gin-swagger) - Gin: gin-swagger - 自動掃 [comments](https://swaggo.github.io/swaggo.io/declarative_comments_format/) build swagger.json - cd 到 project root 目錄, 有 main.go 的地方 - `go get -u github.com/swaggo/swag/cmd/swag` - `swg init` or `$GOPATH/swag init` - 安裝 gin-swagger - `go get -u github.com/swaggo/gin-swagger` - `go get -u github.com/swaggo/files` - [comments](https://github.com/swaggo/swag#general-api-info) - EX: main.go ~~~go // @title Swagger Example API // @version 1.0 // @description This is a sample server celler server. // @termsOfService http://swagger.io/terms/ // @contact.name API Support // @contact.url http://www.swagger.io/support // @contact.email support@swagger.io // @license.name Apache 2.0 // @license.url http://www.apache.org/licenses/LICENSE-2.0.html // @host localhost:8080 // @BasePath /api/v1 // @securityDefinitions.basic BasicAuth // @securityDefinitions.apikey ApiKeyAuth // @in header // @name Authorization // @securitydefinitions.oauth2.application OAuth2Application // @tokenUrl https://example.com/oauth/token // @scope.write Grants write access // @scope.admin Grants read and write access to administrative information // @securitydefinitions.oauth2.implicit OAuth2Implicit // @authorizationUrl https://example.com/oauth/authorize // @scope.write Grants write access // @scope.admin Grants read and write access to administrative information // @securitydefinitions.oauth2.password OAuth2Password // @tokenUrl https://example.com/oauth/token // @scope.read Grants read access // @scope.write Grants write access // @scope.admin Grants read and write access to administrative information // @securitydefinitions.oauth2.accessCode OAuth2AccessCode // @tokenUrl https://example.com/oauth/token // @authorizationUrl https://example.com/oauth/authorize // @scope.admin Grants read and write access to administrative information func main() { r := gin.Default() c := controller.NewController() v1 := r.Group("/api/v1") { accounts := v1.Group("/accounts") { accounts.GET(":id", c.ShowAccount) accounts.GET("", c.ListAccounts) accounts.POST("", c.AddAccount) accounts.DELETE(":id", c.DeleteAccount) accounts.PATCH(":id", c.UpdateAccount) accounts.POST(":id/images", c.UploadAccountImage) } bottles := v1.Group("/bottles") { bottles.GET(":id", c.ShowBottle) bottles.GET("", c.ListBottles) } admin := v1.Group("/admin") { admin.Use(auth()) admin.POST("/auth", c.Auth) } examples := v1.Group("/examples") { examples.GET("ping", c.PingExample) examples.GET("calc", c.CalcExample) examples.GET("groups/:group_id/accounts/:account_id", c.PathParamsExample) examples.GET("header", c.HeaderExample) examples.GET("securities", c.SecuritiesExample) examples.GET("attribute", c.AttributeExample) } } r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) r.Run(":8080") } ~~~ - EX: model ~~~go // ShowAccount godoc // @Summary Show a account // @Description get string by ID // @ID get-string-by-int // @Accept json // @Produce json // @Param id path int true "Account ID" // @Success 200 {object} model.Account // @Header 200 {string} Token "qwerty" // @Failure 400 {object} httputil.HTTPError // @Failure 404 {object} httputil.HTTPError // @Failure 500 {object} httputil.HTTPError // @Router /accounts/{id} [get] func (c *Controller) ShowAccount(ctx *gin.Context) { id := ctx.Param("id") aid, err := strconv.Atoi(id) if err != nil { httputil.NewError(ctx, http.StatusBadRequest, err) return } account, err := model.AccountOne(aid) if err != nil { httputil.NewError(ctx, http.StatusNotFound, err) return } ctx.JSON(http.StatusOK, account) } ~~~ ## React - Hooks - [State Hook](https://zh-hant.reactjs.org/docs/hooks-state.html) - [Hooks API](https://zh-hant.reactjs.org/docs/hooks-reference.html) - ES6 * [ES6 tips](https://www.freecodecamp.org/news/make-your-code-cleaner-shorter-and-easier-to-read-es6-tips-and-tricks-afd4ce25977c/) * [JavaScript ES 6 介紹](https://www.fooish.com/javascript/ES6/) - Spread ~~~js let a = [3, 4, 5]; let b = [ 1, 2, ...a, 6]; console.log(b); // [1, 2, 3, 4, 5, 6] ~~~ ~~~js function foo(a, b, c) { console.log(`a=${a}, b=${b}, c=${c}`)}; let data = [5, 15, 2]; foo( ...data); // a=5, b=15, c=2 ~~~ - Object Literals and Concise Params > When you are creating an object literal from variables, ES6 allows you to omit the key if it is the same as the variable name. ~~~js let a = 4, b = 7; let c = { a: a, b: b }; let concise = { a, b }; console.log(c, concise) // {a: 4, b: 7}, {a: 4, b: 7} ~~~ - `for … of` Loops ~~~js let a = ['a', 'b', 'c', 'd' ]; // ES6 for ( const val of a ) { console.log( val );} // "a" "b" "c" "d" // pre-ES6 for ( const idx in a ) { console.log( idx );} // 0 1 2 3 ~~~ ##### ES6 JavaScript Tutorial: <iframe width="560" height="315" src="https://www.youtube.com/embed/IEf1KAcK6A8" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>