gin을 사용하여 MVC 모델의 웹 응용 프로그램 만들기

62261 단어 golangginGORMtech
【환경】
MacBook Air (M1, 2020)
OS: MacOS Big Sur version11.6
Docker Desktop for Mac version4.5.0
구글의 프레임워크 gin을 사용하여 간단한 MVC 모델 사이트를 제작합니다.

MVC 모델


는 Model, View, Controller와 별도로 정리되는 모델입니다.

Model

  • 상업 논리를 책임진다.구체적으로 데이터베이스에 액세스하고 CRUD를 실행합니다.
  • 데이터를 데이터베이스나 구글에서 쉽게 사용할 수 있는 형식으로 변환한다.
  • View

  • 는 브라우저에 표시되는 등 사용자가 볼 수 있는 확인 부분을 책임진다.
  • 여기는 골롱의 표준 포장>/template를 보기로 합니다.
  • Controller

  • 모델과 View 사이의 다리를 담당합니다.
  • 고객이 보낸 URI를 router에게 보냅니다.Goo 라우팅을 사용하여 CRUD → View로 모델이 얻은 데이터 등을 표시합니다.
  • 비즈니스 논리는 모두 모델에게 맡긴다.(Ctroller는 얇게 만듭니다.)
  • 디렉토리 구조


    mvc_test
    ├── cmd
    │   └── mvc_test
    │       └── main.go
    ├── controller
    │   ├── blog_controller.go
    │   └── router.go
    ├── go.mod
    ├── go.sum
    ├── model
    │   ├── blog_model.go
    │   └── database.go
    └── view
        ├── create.html
        ├── delete.html
        ├── edit.html
        ├── index.html
        └── show.html
    
    MySQL은 Docker를 통해 설치되었으나 글에서 생략되었습니다.
    Docker와 데이터베이스에 관해서는 이 글을 참조하십시오.
    https://zenn.dev/ajapa/articles/443c396a2c5dd1
    https://zenn.dev/ajapa/articles/03dcf8fd12d086

    루트 구현


    먼저 URI를 서버에 던질 때의 라우트입니다.
    router.go
    package controller
    
    import (
    	"github.com/gin-gonic/gin"
    )
    
    func GetRouter() *gin.Engine {
    	r := gin.Default()
    	r.LoadHTMLGlob("view/*html")
    	r.GET("/", ShowAllBlog)
    	r.GET("/show/:id", ShowOneBlog)
    	r.GET("/create", ShowCreateBlog)
    	r.POST("/create", CreateBlog)
    	r.GET("/edit/:id", ShowEditBlog)
    	r.POST("/edit", EditBlog)
    	r.GET("/delete/:id", ShowCheckDeleteBlog)
    	r.POST("/delete", DeleteBlog)
    	return r
    }
    
    router.goo에 gin을 사용하는 루트를 설치했습니다.
    Handler로 등록된 함수는 동일한 Controller로 포장된 블로그입니다.controller.고오 물건이야.
    main.go
    package main
    
    import (
    	"mvc_test/controller"
    )
    
    func main() {
    	router := controller.GetRouter()
    	router.Run(":8080")
    }
    
    controller 포장된router.go의 GetRouter()에 대한 gin을 실행합니다.Engine이 제공됩니다.

    모델 설치


    https://zenn.dev/ajapa/articles/aa9b59dd30c501
    database.goo는 이쪽 기사를 사용합니다.
    패키지만 있는 블로그.model.고와 함께 모델로 삼다.
    blog_model.go
    package model
    
    import (
    	"gorm.io/gorm"
    )
    
    type BlogEntity struct {
    	gorm.Model
    	Title string
    	Body  string
    }
    
    func GetAll() (datas []BlogEntity) {
    	result := Db.Find(&datas)
    	if result.Error != nil {
    		panic(result.Error)
    	}
    	return
    }
    
    func GetOne(id int) (data BlogEntity) {
    	result := Db.First(&data, id)
    	if result.Error != nil {
    		panic(result.Error)
    	}
    	return
    }
    
    func (b *BlogEntity) Create() {
    	result := Db.Create(b)
    	if result.Error != nil {
    		panic(result.Error)
    	}
    }
    
    func (b *BlogEntity) Update() {
    	result := Db.Save(b)
    	if result.Error != nil {
    		panic(result.Error)
    	}
    }
    
    func (b *BlogEntity) Delete() {
    	result := Db.Delete(b)
    	if result.Error != nil {
    		panic(result.Error)
    	}
    }
    
    
    GetAll(모두 취득), GetOne(1건 취득)을 데이터베이스에 등록한 BlogEnity 데이터를 얻습니다.
    BlogEnity의 방법으로는 Create(새로 만들기), Update(업데이트), Delete(삭제)를 들 수 있습니다.(func와 함수 이름 사이를 (b*BlogEnity)로 기술하면 [데이터]입니다.방법()으로 사용할 수 있습니다.

    Controller 설치


    blog_controller.go
    package controller
    
    import (
    	"fmt"
    	"mvc_test/model"
    	"strconv"
    
    	"github.com/gin-gonic/gin"
    )
    
    func ShowAllBlog(c *gin.Context) {
    	datas := model.GetAll()
    	c.HTML(200, "index.html", gin.H{"datas": datas})
    }
    
    func ShowOneBlog(c *gin.Context) {
    	id, _ := strconv.Atoi(c.Param("id"))
    	data := model.GetOne(id)
    	c.HTML(200, "show.html", gin.H{"data": data})
    }
    
    func ShowCreateBlog(c *gin.Context) {
    	c.HTML(200, "create.html", gin.H{})
    }
    
    func CreateBlog(c *gin.Context) {
    	title := c.PostForm("title")
    	body := c.PostForm("body")
    	data := model.BlogEntity{Title: title, Body: body}
    	data.Create()
    	c.Redirect(301, "/")
    }
    
    func ShowEditBlog(c *gin.Context) {
    	id, _ := strconv.Atoi(c.Param("id"))
    	data := model.GetOne(id)
    	c.HTML(200, "edit.html", gin.H{"data": data})
    }
    
    func EditBlog(c *gin.Context) {
    	id, _ := strconv.Atoi(c.PostForm("id"))
    	data := model.GetOne(id)
    	title := c.PostForm("title")
    	data.Title = title
    	body := c.PostForm("body")
    	data.Body = body
    	data.Update()
    	c.Redirect(301, "/")
    }
    
    func ShowCheckDeleteBlog(c *gin.Context) {
    	id, _ := strconv.Atoi(c.Param("id"))
    	data := model.GetOne(id)
    	c.HTML(200, "delete.html", gin.H{"data": data})
    }
    
    func DeleteBlog(c *gin.Context) {
    	id, _ := strconv.Atoi(c.PostForm("id"))
    	fmt.Println("delete:", id)
    	data := model.GetOne(id)
    	data.Delete()
    	c.Redirect(301, "/")
    }
    
    
    router."고"에서 호출된 함수를 설명합니다.
    데이터의 취득, 보존, 성형은 모두 모델에게 맡기고 Controller 내에서는 최대한 줄여야 하는데 처음 사용하는 거라 좋지 않다고 생각해요...

    View 설치


    index.html
    <!DOCTYPE html>
    <html>
        <head>
            <meta httpequiv="ContentType" content="text/html;charset=utf8">
            <title>INDEX</title>
        </head>
        <body>
            <h1>INDEX</h1>
            {{ range .datas }}
            <p>{{ .ID }}: <a href="/show/{{.ID}}">{{.Title}}</a> / <a href="/edit/{{.ID}}">編集</a> / <a href="/delete/{{.ID}}">削除</a></p>
            {{ end }}
            <p><a href="/create">新規作成</a></p>
        </body>
    </html>
    
    블로그 목록을 표시합니다.
    create.html
    <!DOCTYPE html>
    <html>
        <head>
            <meta httpequiv="ContentType" content="text/html;charset=utf8">
            <title>新規作成</title>
        </head>
        <body>
            <form method="POST" action="/create" id="create_form">
                <p>タイトル: <input type="text" name="title" value="" /></p>
                <p>本文:</p>
                <p><textarea name="body" rows="10" cols="40"></textarea></p>
            </form>
            <p>
                <input type="submit" form="create_form" value="作成" /> 
                <a href="/"><input type="button" value="戻る" /></a>
            </p>
        </body>
    </html>
    
    새로 만든 블로그 정보를 입력하고 POST(/create)를 통해 서버에 보냅니다.
    show.html
    <!DOCTYPE html>
    <html>
        <head>
            <meta httpequiv="ContentType" content="text/html;charset=utf8">
            <title>記事表示(ID:{{.data.ID}})</title>
        </head>
        <body>
            <p>タイトル: {{.data.Title}}</p>
            <p>本文:</p>
            <p>{{.data.Body}}</p>
            
            <p><a href="/edit/{{.data.ID}}"><input type="button" value="編集" /></a>
            <a href="/"><input type="button" value="戻る" /></a></p>
        </body>
    </html>
    
    블로그 정보를 표시합니다.
    edit.html
    <!DOCTYPE html>
    <html>
        <head>
            <meta httpequiv="ContentType" content="text/html;charset=utf8">
            <title>記事編集(ID:{.{data.ID}})</title>
        </head>
        <body>
            <form method="POST" action="/edit" id="edit_form">
                <input type="hidden" name="id" value="{{ .data.ID }}" />
                <p>タイトル: <input type="text" name="title" value="{{.data.Title}}" /></p>
                <p>本文:</p>
                <p><textarea name="body" rows="10" cols="40">{{.data.Body}}</textarea></p>
            </form>
        <p>
            <button type="submit" form="edit_form">更新</button>
            <a href="/"><input type="button" value="戻る" /></a>
        </p>
        </body>
    </html>
    
    블로그 정보를 표시하고 변경하여 POST(/edit)를 통해 서버에 보냅니다.
    delete.html
    <!DOCTYPE html>
    <html>
        <head>
            <meta httpequiv="ContentType" content="text/html;charset=utf8">
            <title>記事削除(ID:{{.data.ID}})</title>
        </head>
        <body>
            <form method="POST" action="/delete" id="delete_form">
            <input type="hidden" name="id" value="{{ .data.ID }}" />
            <p>タイトル: {{.data.Title}}</p>
            <p>本文:</p>
            <p>{{.data.Body}}</p>
            <h2>削除しますか?</h2>
        </form>
        <p>
            <button type="submit" form="delete_form">削除</button>
            <a href="/"><input type="button" value="キャンセル" /></a>
        </p>
        </body>
    </html>
    
    삭제할 BlogEnity 정보를 표시하고 POST(/delete)를 통해 서버에 보냅니다.

    참고 자료


    https://dev.classmethod.jp/articles/go-sample-rest-api/
    https://bsblog.casareal.co.jp/archives/4822
    https://bsblog.casareal.co.jp/archives/5121
    https://zenn.dev/7oh/articles/6338a8ccd470c7

    좋은 웹페이지 즐겨찾기