Go - это язык программирования с открытым исходным кодом, который упрощает создание простого, надежного и эффективного программного обеспечения. Go был создан в Google в 2007 году Робертом Гриземером, Робом Пайком и Кеном Томпсоном. Go - это скомпилированный статически типизированный язык.

PS: Эта статья не является введением в язык программирования Go, она является промежуточной.

В рамках этого руководства мы создадим RESTful API для приложения "Телефонная книга".

ОТДЫХ, RESTful, WTH !!

REST - это аббревиатура от слова "репрезентативная передача состояния". Это архитектура веб-стандартов и протокол HTTP. Протокол REST описывает шесть (6) ограничений:

  1. Единый интерфейс
  2. Кэшируемый
  3. Клиент-Сервер
  4. Без гражданства
  5. Код по запросу
  6. Многоуровневая система

REST состоит из таких методов, как базовый URL-адрес, типы мультимедиа и т. Д. Приложения RESTful используют HTTP-запросы для выполнения операций CRUD.

Настраивать

Чтобы начать писать наш API, нам нужно настроить нашу среду. Получите последнюю версию Go (на момент написания статьи это 1.8.3) › здесь . После установки Go у вас должна быть установлена ​​переменная $GOPATH sys. Нам нужен каталог Project для хранения нашего источника, мы его создаем:

$ mkdir -p $GOPATH/src/github/{your username}/rest-api

Эта команда создаст папку проекта rest-api в вашем домашнем каталоге Go.

$ cd rest-api

Далее мы создаем main.go файл

Маршрутизатор

Нам нужно будет использовать mux для маршрутизации запросов, поэтому для этого нам понадобится пакет Go (mux означает мультиплексор HTTP-запросов, который сопоставляет входящий запрос со списком маршрутов (зарегистрированные)). В каталоге rest-api давайте потребуем зависимость (скорее, пакет).

rest-api$ go get github.com/gorilla/mux

Настраиваем наш main.go файл

package main
import (
    "encoding/json"
    "log"
    "net/http"
    "github.com/gorilla/mux"
)
// our main function
func main() {
    router := mux.NewRouter()
    log.Fatal(http.ListenAndServe(":8000", router))
}

Если вы запустите этот файл, он на самом деле ни на что не отвечает, поэтому нам нужно написать наши конечные точки. Для api телефонной книги нам потребуются эти s:

  • /people (GET) - ›Все лица в документе телефонной книги (базе данных)
  • /people/{id} (GET) - ›Найдите одного человека
  • /people/{id} (POST) - ›Создать нового человека
  • /people/{id} (УДАЛИТЬ) - ›Удалить человека

Мы должны написать дескриптор маршрутов для этих s, а также их методы.

// fun main()
func main() {
    router := mux.NewRouter()
    router.HandleFunc("/people", GetPeople).Methods("GET")
    router.HandleFunc("/people/{id}", GetPerson).Methods("GET")
    router.HandleFunc("/people/{id}", CreatePerson).Methods("POST")
    router.HandleFunc("/people/{id}", DeletePerson).Methods("DELETE")
    log.Fatal(http.ListenAndServe(":8000", router))
}

Запустим нашу программу

rest-api$ go build
rest-api$ ./rest-api

Вышеупомянутое приведет к ошибке, мы не создали функции для обработки этих запросов. Давайте создадим их (пока пусто):

...
func GetPeople(w http.ResponseWriter, r *http.Request) {}
func GetPerson(w http.ResponseWriter, r *http.Request) {}
func CreatePerson(w http.ResponseWriter, r *http.Request) {}
func DeletePerson(w http.ResponseWriter, r *http.Request) {}
...

Повторное построение файла не должно возвращать никаких ошибок, но функции пусты. Каждый метод принимает два параметра w и r, которые относятся к типам http.ResponseWriter и *http.Request. Эти два параметра заполняются после получения запроса.

Извлечь все данные из телефонной книги

Давайте напишем код, чтобы получить все записи визг шин »› У нас нет данных… да, давайте заполним вручную (базы данных выходят за рамки этого руководства). Давайте добавим структуру Person (воспринимайте ее как объект) и структуру Address, а также переменную people для заполнения.

//main.go
...
type Person struct {
    ID        string   `json:"id,omitempty"`
    Firstname string   `json:"firstname,omitempty"`
    Lastname  string   `json:"lastname,omitempty"`
    Address   *Address `json:"address,omitempty"`
}
type Address struct {
    City  string `json:"city,omitempty"`
    State string `json:"state,omitempty"`
}
var people []Person
...

Когда наш structs готов, давайте вручную добавим записи в people срез:

// main()
...
people = append(people, Person{ID: "1", Firstname: "John", Lastname: "Doe", Address: &Address{City: "City X", State: "State X"}})
people = append(people, Person{ID: "2", Firstname: "Koko", Lastname: "Doe", Address: &Address{City: "City Z", State: "State Y"}})
people = append(people, Person{ID: "3", Firstname: "Francis", Lastname: "Sunday"})
...

С нашим набором данных позволяет получить все из фрагмента людей:

//main.go
...
func GetPeople(w http.ResponseWriter, r *http.Request) {
    json.NewEncoder(w).Encode(people)
}
...

Перестроив (go build && ./rest-api) и протестировав с почтальоном, мы получили ответ в формате JSON. Перейдите к localhost:8080/people

Получите единые данные

Теперь давайте напишем, чтобы показать одного человека:

// main.go
...
func GetPerson(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    for _, item := range people {
    if item.ID == params["id"]
}
}
...

Функция GetPerson здесь просматривает отображенный names из входящего запроса, чтобы проверить, совпадают ли отправленные id параметры с какими-либо в структуре Person.

Другие конечные точки

Давай закончим наши другие s (CreatePerson, DeletePerson)

func CreatePerson(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    var person Person
    _ = json.NewDecoder(r.Body).Decode(&person)
    person.ID = params["id"]
    people = append(people, person)
    json.NewEncoder(w).Encode(people)
}
func DeletePerson(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    for index, item := range people {
        if item.ID == params["id"] {
            people = append(people[:index], people[index+1]...)
            break
    }
    json.NewEncoder(w).Encode(people)
}
}

Собираем все вместе

Теперь наш Final main.go файл должен выглядеть так:

package main
import (
    "encoding/json"
    "github.com/gorilla/mux"
    "log"
    "net/http"
)
// The person Type (more like an object)
type Person struct {
    ID        string   `json:"id,omitempty"`
    Firstname string   `json:"firstname,omitempty"`
    Lastname  string   `json:"lastname,omitempty"`
    Address   *Address `json:"address,omitempty"`
}
type Address struct {
    City  string `json:"city,omitempty"`
    State string `json:"state,omitempty"`
}
var people []Person
// Display all from the people var
func GetPeople(w http.ResponseWriter, r *http.Request) {
    json.NewEncoder(w).Encode(people)
}
// Display a single data
func GetPerson(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    for _, item := range people {
        if item.ID == params["id"] {
            json.NewEncoder(w).Encode(item)
            return
        }
    }
    json.NewEncoder(w).Encode(&Person{})
}
// create a new item
func CreatePerson(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    var person Person
    _ = json.NewDecoder(r.Body).Decode(&person)
    person.ID = params["id"]
    people = append(people, person)
    json.NewEncoder(w).Encode(people)
}
// Delete an item
func DeletePerson(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    for index, item := range people {
        if item.ID == params["id"] {
            people = append(people[:index], people[index+1:]...)
            break
        }
        json.NewEncoder(w).Encode(people)
    }
}
// main function to boot up everything
func main() {
    router := mux.NewRouter()
    people = append(people, Person{ID: "1", Firstname: "John", Lastname: "Doe", Address: &Address{City: "City X", State: "State X"}})
    people = append(people, Person{ID: "2", Firstname: "Koko", Lastname: "Doe", Address: &Address{City: "City Z", State: "State Y"}})
    router.HandleFunc("/people", GetPeople).Methods("GET")
    router.HandleFunc("/people/{id}", GetPerson).Methods("GET")
    router.HandleFunc("/people/{id}", CreatePerson).Methods("POST")
    router.HandleFunc("/people/{id}", DeletePerson).Methods("DELETE")
    log.Fatal(http.ListenAndServe(":8000", router))
}

Тестирование

Чтобы протестировать свой API, либо просмотрите их в браузере (вам понадобится расширение JSON форматировщика, чтобы четко читать вывод), либо используйте Postman.

Исходный код этого руководства можно найти здесь

Заключение

Вы только что увидели, как создать очень простой RESTful API с помощью языка программирования Go. Хотя мы использовали фиктивные данные вместо базы данных, мы увидели, как создавать конечные точки, которые выполняют различные операции с данными JSON и срезами GoLang. Я что-то важное пропустил? Дай мне знать в комментариях.

:)