DevGang
Авторизоваться

Создание базового RESTful (CRUD) с помощью Golang и MySQL 

Мы будем разрабатывать приложение, которое предоставляет базовый сервер REST-API для операций CRUD для управления пользователями (id, firstName, lastName, age).

Настройка приложения

Начнем с создания нашей корневой папки

mkdir rest-go-demo && cd rest-go-demo

Это создаст папку с именем «rest-go-demo».

Теперь давайте начнем с инициализации и добавления go-модулей, необходимых для нашего приложения.

go mod init 
go get github.com/gorilla/mux 
go get github.com/jinzhu/gorm 
go get github.com/go-sql-driver/mysql

Мы будем использовать управление зависимостями, представленное Golang в виде их-модулей.

«Go mod init» используется для инициализации корневого приложения, а зависимости можно отслеживать с помощью go.mod, созданного после выполнения вышеуказанной команды.

Нам понадобятся определенные пакеты, чтобы помочь в нашем путешествии:

1. gorilla/mux Для создания маршрутов и обработчиков HTTP для наших конечных точек

2. jinzhu/gorm Инструмент ORM для MySQL.

3. go-sql-driver/mysql драйвер MYSQL.

Настройка MySQL

Давайте начнем с создания базы данных, соответствующей нашим потребностям.

CREATE DATABASE learning;

Давайте создадим структуру для управления конфигурацией нашей базы данных, которая будет использоваться для создания соединения с базой данных.

package database

import "fmt"

//Config to maintain DB configuration properties
type Config struct {
	ServerName string
	User       string
	Password   string
	DB         string
}

var getConnectionString = func(config Config) string {
	connectionString := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&collation=utf8mb4_unicode_ci&parseTime=true&multiStatements=true", config.User, config.Password, config.ServerName, config.DB)
	return connectionString
}

Теперь давайте создадим клиента для управления и создания подключений к нашей базе данных.

package database

import (
	"log"

	"github.com/jinzhu/gorm"
)

//Connector variable used for CRUD operation's
var Connector *gorm.DB

//Connect creates MySQL connection
func Connect(connectionString string) error {
	var err error
	Connector, err = gorm.Open("mysql", connectionString)
	if err != nil {
		return err
	}
	log.Println("Connection was successful!!")
	return nil
}

Давайте проверим, может ли наш клиент подключиться к нашей базе данных или нет!!

package main

import (
	"rest-go-demo/database"

	_ "github.com/jinzhu/gorm/dialects/mysql" //Required for MySQL dialect
)

func main() {
	config :=
		database.Config{
			ServerName: "localhost:3306",
			User:       "root",
			Password:   "root",
			DB:         "learning",
		}

	connectionString := database.GetConnectionString(config)
	err := database.Connect(connectionString)
	if err != nil {
		panic(err.Error())
	}
}
$ go run main.go 
2021/02/14 16:56:34 Connection was successful!!

Теперь давайте создадим нашу простую структуру Person, которая будет нашей моделью.

type Person struct {
ID        string `json:"id"`
FirstName string `json:"firstName"`
LastName  string `json:"lastName"`
Age       string `json:"age"`
}

Создаем простой HTTP-сервер с gorilla/mux

Мы будем использовать gorilla/mux для создания простого сервера для обработки наших HTTP-запросов.

package main

import (
	"log"
	"net/http"

	"github.com/gorilla/mux"
)

func main() {
	log.Println("Starting the HTTP server on port 8090")
	router := mux.NewRouter().StrictSlash(true)
	log.Fatal(http.ListenAndServe(":8090", router))
}

HTTP-сервер, работающий на порту 8090, будет запущен для нашего использования.

Теперь давайте добавим нашу конечную точку REST и продолжим наше путешествие.

POST/CREATE

Мы начнем с добавления маршрута /create/ к нашему маршрутизатору для обслуживания конечной точки, которая будет создавать нового человека при каждом запуске.

router.HandleFunc("/create",createPerson).Methods("POST")

Давайте создадим соответствующую функцию createPerson(), которая будет принимать данные POST-запроса и создавать новую запись о человеке в БД.

Мы сделаем то же самое, сначала распаковав данные JSON, полученные из тела, в нашу структуру Person, созданную выше, а затем вставим данные, создав новую запись.

func createPerson(w http.ResponseWriter, r *http.Request) {
	requestBody, _ := ioutil.ReadAll(r.Body)
	var person entity.Person
	json.Unmarshal(requestBody, &person)

	database.Connector.Create(person)
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusCreated)
	json.NewEncoder(w).Encode(person)
}

GET/SELECT

Аналогично, тому как мы добавили обработчик и соответствующую функцию для POST, мы добавим /get/{id} к нашему маршрутизатору для получения данных

router.HandleFunc("/get/{id}", getPersonByID).Methods("GET")

Давайте добавим соответствующую функцию getPersonByID(), которая будет использовать параметр запроса «id» для получения соответствующих данных и возврата ответа JSON.

Здесь мы бы отменили процедуру, которую мы выполняли при создании конечной точки POST, мы будем маршалировать структуру человека, полученную из базы данных, в JSON и создать HTTP-ответ.

func getPersonByID(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	key := vars["id"]

	var person entity.Person
	database.Connector.First(&person, key)
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(person)
}

PUT/UPDATE

Теперь я могу предположить, что вы уже догадались, что будет дальше с нашим маршрутизатором и соответствующими функциями.

router.HandleFunc("/update/{id}", updatePersonByID).Methods("PUT")

updatePersonByID() примет данные POST-запроса, распакует JSON в структуру person и обновит соответственно

func updatePersonByID(w http.ResponseWriter, r *http.Request) {
	requestBody, _ := ioutil.ReadAll(r.Body)
	var person entity.Person
	json.Unmarshal(requestBody, &person)
	database.Connector.Save(&person)

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(person)
}

DELETE/DELETE

router.HandleFunc("/delete/{id}", deletPersonByID).Methods("DELETE")

deletePersonByID() удалит «id», переданный в параметре запроса, и удалит соответствующую запись из базы данных.

func deletPersonByID(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	key := vars["id"]

	var person entity.Person
	id, _ := strconv.ParseInt(key, 10, 64)
	database.Connector.Where("id = ?", id).Delete(&person)
	w.WriteHeader(http.StatusNoContent)
}

Теперь, когда все наши конечные точки на месте, давайте объединим их все и протестируем наши CRUD операции.

Мы сделаем это, выполнив следующие команды

go mod tidy
go build
./rest-go-demo

Создание человека

Получение по ID

Обновление данных

Удаление

#Golang
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

Поделитесь своим опытом, расскажите о новом инструменте, библиотеке или фреймворке. Для этого не обязательно становится постоянным автором.

Попробовать

В подарок 100$ на счет при регистрации

Получить