Нужно ли создавать клиент Firestore для запроса с Google App Engine? - PullRequest
0 голосов
/ 11 октября 2018

Я не совсем понимаю, как к этому подойти.

Похоже, что GAE хочет, чтобы каждая клиентская библиотека использовала контекст. Контекст ограничен областью http.Request.

Я ранееИмею опыт работы примерно так:

main.go

type server struct {
    db *firestore.Client
}

func main() {
    // Setup server
    s := &server{db: NewFirestoreClient()}

    // Setup Router
    http.HandleFunc("/people", s.peopleHandler())

    // Starts the server to receive requests
    appengine.Main()
}

func (s *server) peopleHandler() http.HandlerFunc {
    // pass context in this closure from main?
    return func(w http.ResponseWriter, r *http.Request) {
        ctx := r.Context() // appengine.NewContext(r) but should it inherit from background somehow?
        s.person(ctx, 1)
        // ...
    }
}

func (s *server) person(ctx context.Context, id int) {
    // what context should this be?
    _, err := s.db.Client.Collection("people").Doc(uid).Set(ctx, p)
    // handle client results
}

firebase.go

// Firestore returns a warapper for client
type Firestore struct {
    Client *firestore.Client
}

// NewFirestoreClient returns a firestore struct client to use for firestore db access
func NewFirestoreClient() *Firestore {
    ctx := context.Background()
    client, err := firestore.NewClient(ctx, os.Getenv("GOOGLE_PROJECT_ID"))
    if err != nil {
        log.Fatal(err)
    }

    return &Firestore{
        Client: client,
    }
}

Это имеет большое значение для определения масштаба клиента проекта.Например, зависание от server{db: client} и присоединение обработчиков к этой структуре или необходимость передавать его через внедрение зависимостей в запросе.

Я замечаю, что вызовы с использованием клиента требуют другого контекста.Так что, возможно, это должно выглядеть так:

  1. main.go создать ctx := context.Background()
  2. main.go передать это новому клиенту
  3. handler ctx := appengine.NewContext(r)

В основном начальная установка не имеет значения вне context.Background(), потому что новые запросы имеют контекст, отличный от App Engine?

Я мог бы передать ctx в обработчик из main, а затем отключить NewContextоб этом + запрос?

Какой идиоматический подход к этому?

примечание: у меня были методы firestore из структуры Firestore также в предыдущих итерациях ...

1 Ответ

0 голосов
/ 12 февраля 2019

Вы должны повторно использовать экземпляр firestore.Client для нескольких вызовов.Однако это было невозможно в старой среде исполнения Go в стандарте GAE.Поэтому в этом случае вы должны создать новый firestore.Client для каждого запроса.

Но если вы используете новую среду выполнения Golang 1.11 для стандарта GAE, тогда вы можете свободно использовать любой контекст, который вам нравится.В этом случае вы можете инициализировать firestore.Client в функции main() или в функции init(), используя фоновый контекст.Затем вы можете выполнять вызовы API в обработчиках запросов, используя контекст запроса.

package main

var client *firestore.Client

func init() {
  var err error
  client, err = firestore.NewClient(context.Background())
  // handle errors as needed
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
  doc := client.Collection("cities").Doc("Mountain View")
  doc.Set(r.Context(), someData)
  // rest of the handler logic
}

Вот пример приложения GAE, которое я реализовал с использованием Go 1.11 и Firestore, которое демонстрирует вышеуказанный шаблон: https://github.com/hiranya911/firecloud/blob/master/crypto-fire-alert/cryptocron/web/main.go

Подробнее о поддержке Go 1.11 в GAE: https://cloud.google.com/appengine/docs/standard/go111/go-differences

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...