В этом блоге мы разрабатываем с вами спокойный API. Небольшая инструкция о том, что такое отдых, имеет решающее значение. Затем продолжение разработки API является нашей основной задачей.

Что такое Rest API? (REпрезентация State Ttransfer)

API – это интерфейс прикладного программирования. Он состоит из набора правил и используется для того, чтобы программы могли общаться друг с другом. REST определяет, как выглядит API. Когда разработчики создают свой API, они следуют набору ограничений. Это приводит к некоторым конкретным URL-адресам для получения части данных. Каждый URL называется запросом. Данные, отправленные вам обратно, называются ответом.

Наш язык программирования Go. Кроме того, нам помогает Gin Web Framework. Я создал серию, которая изучает документацию. Эта серия включает в себя 5 основных блогов для понимания основ Go. Если вы в настоящее время новичок, это может быть хорошо для вас. Давайте начнем.

Gin упрощает многие задачи кодирования, связанные с созданием веб-приложений, включая веб-службы. В этом руководстве вы будете использовать Gin для маршрутизации запросов, получения сведений о запросах и маршалинга JSON для ответов.

Мы создадим API приложения для создания задач. Каждая задача будет состоять из идентификатора, названия, лица и информации. Каждый может добавить задачу и прочитать все задачи. Непосредственно можно сказать, что мы проектируем конечные точки. 🥳

/task
  - GET  - get list of all task
  - POST - Add a new task
/task
  - Get task by ID

Мы разработали, как это выглядит. Давайте начнем веселую часть. (Здесь я использовал macOS и приложение iterm2. Если вы пользователь Windows, вы можете продолжить с cmd. Linux такой же, как macOS.)

Откройте терминал и создайте папку, где хотите — я создал на рабочем столе. Затем инициализируйте файл go. Откройте эту папку в текстовом редакторе.

// terminal
$ cd Desktop
$ mkdir task-app-web
$ cd task-app-web
$ go mod init example/task-app-web
$ touch main.go
// main.go
package main
type task struct { 
	ID          string `json:"id"` // we will use json so we need specify what a field’s name should be
	Title       string `json:"title"`
	Person      string `json:"artist"`
	Information string `json:"information"`
}
// Also we can create a simple data. In real life, the data come from database.
// In here, we will store data in localy.
var tasks = []task{
	{ID: "BS-1", Title: "Create an API", Person: "Kuzey", Information: "Create a simple task api that people create some tasks and reach all of the task."},
	{ID: "BS-2", Title: "Write a blog", Person: "Kuzey", Information: "Write a blog that people who interested in Go can write create their API."},
	{ID: "BS-3", Title: "Make a coffe for us", Person: "John", Information: "29.12.2021 we have a coffe talk session. Can we make a coffe for us?"},
	{ID: "BS-4", Title: "Order some food", Person: "May", Information: "Order some food for lunch."},
}
func main() {}

Здесь мы описываем наши объекты, как они должны выглядеть. Структура задачи показывает нам параметры, а задачи — это срез, который содержит задачу. Теперь нам нужно использовать gin framework для использования метода GET HTTP. Во-первых, импортируйте пакеты, затем напишите функцию с именем getTask(). Мы будем использовать функцию getTask() внутри router.GET() в основной функции. (Не паникуйте, мы увидим каждого из них)

// main.go
package main
import (
    "net/http"
    "github.com/gin-gonic/gin"
)
type task struct { 
	ID          string `json:"id"` // we will use json so we need specify what a field’s name should be
	Title       string `json:"title"`
	Person      string `json:"artist"`
	Information string `json:"information"`
}
// Also we can create a simple data. In real life, the data come from database.
// In here, we will store data in localy.
var tasks = []task{
	{ID: "BS-1", Title: "Create an API", Person: "Kuzey", Information: "Create a simple task api that people create some tasks and reach all of the task."},
	{ID: "BS-2", Title: "Write a blog", Person: "Kuzey", Information: "Write a blog that people who interested in Go can write create their API."},
	{ID: "BS-3", Title: "Make a coffe for us", Person: "John", Information: "29.12.2021 we have a coffe talk session. Can we make a coffe for us?"},
	{ID: "BS-4", Title: "Order some food", Person: "May", Information: "Order some food for lunch."},
}
// getTasks responds with the list of all albums as JSON.
func getTasks(c *gin.Context) {
    c.IndentedJSON(http.StatusOK, tasks)
}
func main() {}

В основной функции нам нужно создать роутер с помощью gin. Внутри gin функция Default() помогает создать простой роутер (https://pkg.go.dev/github.com/gin-gonic/gin#Default). И используйте функцию GET, чтобы связать метод GET HTTP.

// main.go
package main
import (
    "net/http"
    "github.com/gin-gonic/gin"
)
type task struct { 
	ID          string `json:"id"` // we will use json so we need specify what a field’s name should be
	Title       string `json:"title"`
	Person      string `json:"artist"`
	Information string `json:"information"`
}
// Also we can create a simple data. In real life, the data come from database.
// In here, we will store data in localy.
var tasks = []task{
	{ID: "BS-1", Title: "Create an API", Person: "Kuzey", Information: "Create a simple task api that people create some tasks and reach all of the task."},
	{ID: "BS-2", Title: "Write a blog", Person: "Kuzey", Information: "Write a blog that people who interested in Go can write create their API."},
	{ID: "BS-3", Title: "Make a coffe for us", Person: "John", Information: "29.12.2021 we have a coffe talk session. Can we make a coffe for us?"},
	{ID: "BS-4", Title: "Order some food", Person: "May", Information: "Order some food for lunch."},
}
// getTasks responds with the list of all albums as JSON.
func getTasks(c *gin.Context) {
    c.IndentedJSON(http.StatusOK, tasks)
}
func main() {
    router := gin.Default()
    router.GET("/albums", getTasks)
    router.Run("localhost:8080")
}

Run подключает маршрутизатор к http.Server и начинает прослушивать и обслуживать HTTP-запросы. Это ярлык для http.ListenAndServe(addr, router) Примечание: этот метод заблокирует вызывающую горутину на неопределенный срок, если не произойдет ошибка. (https://pkg.go.dev/github.com/gin-gonic/gin#Engine.Run)

// terminal
$ go get .
go get: added github.com/gin-gonic/gin
$ go run .
$ curl <https://localhost:8080/tasks>

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

// main.go
package main
import (
    "net/http"
    "github.com/gin-gonic/gin"
)
type task struct { 
	ID          string `json:"id"` // we will use json so we need specify what a field’s name should be
	Title       string `json:"title"`
	Person      string `json:"artist"`
	Information string `json:"information"`
}
// Also we can create a simple data. In real life, the data come from database.
// In here, we will store data in localy.
var tasks = []task{
	{ID: "BS-1", Title: "Create an API", Person: "Kuzey", Information: "Create a simple task api that people create some tasks and reach all of the task."},
	{ID: "BS-2", Title: "Write a blog", Person: "Kuzey", Information: "Write a blog that people who interested in Go can write create their API."},
	{ID: "BS-3", Title: "Make a coffe for us", Person: "John", Information: "29.12.2021 we have a coffe talk session. Can we make a coffe for us?"},
	{ID: "BS-4", Title: "Order some food", Person: "May", Information: "Order some food for lunch."},
}
// getTasks responds with the list of all albums as JSON.
func getTasks(c *gin.Context) {
    c.IndentedJSON(http.StatusOK, tasks)
}
// postTask
func postTask(c *gin.Context) {
    var newTask task
    // Call BindJSON to bind the received JSON to newTask.
    if err := c.BindJSON(&newTask); err != nil {
        return
    }
    // Add the new album to the slice.
    tasks = append(tasks, newTask)
    c.IndentedJSON(http.StatusCreated, newTask)
}
func main() {
    router := gin.Default()
    router.GET("/tasks", getTasks)
    router.POST("/tasks", postTasks)
    router.Run("localhost:8080")
}

Context.BindJSON привязывает тело запроса к newTask. Кроме того, к ответу добавляется код состояния 201.

// terminal
$ curl <https://localhost:8080/tasks> \\                                                                                                                         
	    --include \\
	    --header "Content-Type: application/json" \\
	    --request "POST" \\
	    --data '{"id": "BS-5","title": "POST request","person": "kuzey","information": "create a tasks in post request" }'
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Date: Thu, 30 Dec 2021 19:48:34 GMT
Content-Length: 72
$ curl <https://localhost:8080/tasks>
[
    {
        "id": "BS-1",
        "title": "Create an API",
        "person": "Kuzey",
        "information": "Create a simple task api that people create some tasks and reach all of the task."
    },
    {
        "id": "BS-2",
        "title": "Write a blog",
        "person": "Kuzey",
        "information": "Write a blog that people who interested in Go can write create their API."
    },
    {
        "id": "BS-3",
        "title": "Make a coffe for us",
        "person": "John",
        "information": "29.12.2021 we have a coffe talk session. Can we make a coffe for us?"
    },
    {
        "id": "BS-4",
        "title": "Order some food",
        "person": "May",
        "information": "Order some food for lunch."
    },
    {
        "id": "BS-5",
        "title": "POST request",
        "person": "kuzey",
        "information": "create a tasks in post request"
    }
]%

Иногда мы хотим добраться до определенного элемента. В этой функции мы создадим запрос GET с определенным идентификатором. Допустим, имя функции — getTaskByID.

// main.go
package main
import (
    "net/http"
    "github.com/gin-gonic/gin"
)
type task struct { 
	ID          string `json:"id"` // we will use json so we need specify what a field’s name should be
	Title       string `json:"title"`
	Person      string `json:"artist"`
	Information string `json:"information"`
}
// Also we can create a simple data. In real life, the data come // from database.
// In here, we will store data in localy.
var tasks = []task{
	{ID: "BS-1", Title: "Create an API", Person: "Kuzey",   Information: "Create a simple task api that people create some tasks and reach all of the task."},
	{ID: "BS-2", Title: "Write a blog", Person: "Kuzey", Information: "Write a blog that people who interested in Go can write create their API."},
	{ID: "BS-3", Title: "Make a coffe for us", Person: "John", Information: "29.12.2021 we have a coffe talk session. Can we make a coffe for us?"},
	{ID: "BS-4", Title: "Order some food", Person: "May", Information: "Order some food for lunch."},
}
// getTasks responds with the list of all albums as JSON.
func getTasks(c *gin.Context) {
    c.IndentedJSON(http.StatusOK, tasks)
}
// postTask
func postTask(c *gin.Context) {
    var newTask task
    // Call BindJSON to bind the received JSON to newTask.
    if err := c.BindJSON(&newTask); err != nil {
        return
    }
    // Add the new album to the slice.
    tasks = append(tasks, newTask)
    c.IndentedJSON(http.StatusCreated, newTask)
}
// get task by Id
func getTaskByID(c *gin.Context) {
    id := c.Param("id")
		println(id)
    // Loop over the list of tasks, looking for
    // an album whose ID value matches the parameter.
    for _, a := range tasks {
        if a.ID == id {
            c.IndentedJSON(http.StatusOK, a)
            return
        }
    }
    c.IndentedJSON(http.StatusNotFound, gin.H{"message": "task not found"})
}
func main() {
    router := gin.Default()
    router.GET("/tasks", getTasks)
    router.POST("/tasks", postTask)
    router.GET("/tasks/:id", getTaskByID)
    router.Run("localhost:8080")
}

Context.Param получил параметр пути идентификатора из URL-адреса. Когда вы сопоставляете этот обработчик с путем, вы включаете заполнитель для параметра в путь. http.StatisNotFound возвращает HTTP 404.

// terminal
$ go run .
$ curl <https://localhost:8080/tasks/BS-2>
{
    "id": "BS-2",
    "title": "Write a blog",
    "artist": "Kuzey",
    "information": "Write a blog that people who interested in Go can write create their API."
}%
$ curl <https://localhost:8080/tasks/BS-6>
{
    "message": "task not found"
}%

Этот пост в блоге является личными заметками 🙂 Если вас это больше интересует, вам нужно проверить сайт https://go.dev/doc/tutorial/web-service-gin.