# 達易技術分享交流
<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>