Pengembangan Fungsi Lokal

Fungsi Cloud Run mendukung beberapa metode untuk menjalankan fungsi Anda di luar lingkungan deployment target. Hal ini sangat berguna untuk pengembangan iteratif, dan untuk situasi ketika Anda ingin menguji fungsi sebelum melakukan deployment.

Kemampuan untuk menjalankan fungsi tanpa men-deploy-nya dapat menyederhanakan pengujian lokal, kepatuhan terhadap pembatasan lokalitas data, dan deployment multi-cloud:

  • Pembatasan lokalitas data: Uji fungsi Anda secara lokal tanpa mengakses data produksi, untuk menghindari pelanggaran terhadap aturan lokalitas data organisasi Anda.

  • Deployment multicloud: Deployment fungsi multicloud adalah pola yang sudah mapan untuk memitigasi risiko periode nonaktif di lingkungan yang sangat mendukung keandalan. Men-deploy fungsi ke lingkungan selain fungsi Cloud Run itu sendiri dapat mengurangi risiko aplikasi mengalami periode nonaktif yang tidak direncanakan.

Mengembangkan fungsi secara lokal menggunakan Functions Framework

Anda dapat mengembangkan dan menguji fungsi secara lokal menggunakan Functions Framework. Mengembangkan fungsi secara lokal dapat membantu Anda menguji kode tanpa harus mem-build ulang penampung fungsi. Hal ini dapat menghemat waktu dan mempermudah pengujian fungsi Anda.

Cloud Run menggunakan library Framework Functions open source untuk menggabungkan fungsi yang di-deploy ke dalam aplikasi HTTP persisten.

Framework Functions juga dapat berjalan pada platform lain yang mendukung bahasa itu sendiri, termasuk mesin lokal Anda, server lokal, dan Compute Engine.

Menginstal dependensi

Di direktori fungsi, instal library Framework Functions untuk bahasa Anda:

Node.js

npm install --save-dev @google-cloud/functions-framework

Python

pip3 install functions-framework

Go

go install github.com/GoogleCloudPlatform/functions-framework-go/funcframework

Java

Maven

Jika Anda menggunakan Maven, tambahkan kode berikut ke file pom.xml:

<dependency>
  <groupId>com.google.cloud.functions</groupId>
  <artifactId>functions-framework-api</artifactId>
  <version>1.1.0</version>
  <scope>provided</scope>
</dependency>

Gradle

Jika Anda menggunakan Gradle, tambahkan kode berikut ke file build.gradle:

dependencies {
  // Every function needs this dependency to get the Functions Framework API.
  compileOnly 'com.google.cloud.functions:functions-framework-api:1.1.0'

  // To run function locally using Functions Framework's local invoker
  invoker 'com.google.cloud.functions.invoker:java-function-invoker:1.3.1'
}

Lihat library Framework Functions Java untuk mengetahui informasi selengkapnya.

C#

Perintah berikut menggunakan Template .NET untuk membuat codebase fungsi .NET baru dengan library Framework Functions.NET sebagai dependensi:

# HTTP functions
dotnet new gcf-http

# CloudEvent functions
dotnet new gcf-event

Ruby

Di Ruby, Framework Functions harus ditambahkan ke dependensi fungsi Anda untuk men-deploynya ke Cloud Run:

bundle add functions_framework

PHP

composer require google/cloud-functions-framework

Mengonfigurasi Framework Functions

Sebelum menjalankan fungsi menggunakan Framework Functions, pertama-tama Anda harus menentukan jenis dan nama fungsi yang ingin dijalankan. Atribut ini dapat ditentukan sebagai flag antarmuka command line (CLI) atau sebagai variabel lingkungan.

Jenis fungsi yang didukung

Framework Functions mendukung kedua jenis fungsi yang didukung oleh fungsi Cloud Run. Semua runtime bahasa mendukung jenis tanda tangan http dan cloudevent.

Jenis fungsi Jenis tanda tangan Deskripsi Mendukung Runtime
Fungsi yang dipicu HTTP http Fungsi yang menerima dan merespons permintaan HTTP. Semua runtime
Fungsi CloudEvent cloudevent Format peristiwa standar industri. Semua runtime

Menentukan fungsi yang akan dijalankan

Sebelum menjalankan fungsi dengan Framework Functions, Anda harus terlebih dahulu menentukan fungsi mana dalam kode Anda yang akan dijalankan. Untuk sebagian besar bahasa, Anda dapat melakukannya dengan menentukan nama metode fungsi target seperti yang ditunjukkan pada tabel berikut. Perhatikan bahwa ada pengecualian untuk aturan ini untuk runtime Java dan .NET.

Petunjuk per bahasa

Lihat tabel berikut untuk daftar opsi konfigurasi yang didukung oleh setiap bahasa.

Node.js

Argumen CLI Variabel Lingkungan Deskripsi
--port PORT Port untuk memproses permintaan. (Default: 8080)
--target FUNCTION_TARGET Nama fungsi export yang akan dipanggil. (Default: function)
--signature-type FUNCTION_SIGNATURE_TYPE Jenis tanda tangan yang digunakan oleh fungsi Anda. Dapat berupa http (default) atau cloudevent.

Python

Argumen CLI Variabel Lingkungan Deskripsi
--port PORT Port untuk memproses permintaan. (Default: 8080)
--target FUNCTION_TARGET Nama fungsi export yang akan dipanggil. (Default: function)
--signature-type FUNCTION_SIGNATURE_TYPE Jenis tanda tangan yang digunakan oleh fungsi Anda. Dapat berupa http (default) atau cloudevent.

Go

Variabel Lingkungan Deskripsi
PORT Port untuk memproses permintaan. (Default: 8080)

Java

Nama Argumen Variabel Lingkungan Deskripsi
run.port PORT Port untuk memproses permintaan. (Default: 8080)
run.functionTarget FUNCTION_TARGET Nama fungsi export yang akan dipanggil. (Default: function)

C#

Argumen CLI Variabel Lingkungan Deskripsi
--port PORT Port untuk memproses permintaan. (Default: 8080)
--target (atau hanya argumen) FUNCTION_TARGET classname fungsi yang akan dipanggil. (Default: function)

Ruby

Argumen CLI Variabel Lingkungan Deskripsi
--port PORT Port untuk memproses permintaan. (Default: 8080)
--target FUNCTION_TARGET Nama fungsi export yang akan dipanggil. (Default: function)

PHP

Variabel Lingkungan Deskripsi
FUNCTION_TARGET Nama fungsi yang akan dipanggil. (Default: function)
FUNCTION_SIGNATURE_TYPE Jenis tanda tangan yang digunakan oleh fungsi Anda. Dapat berupa http (default) atau cloudevent.

Ikuti petunjuk ini untuk mengonfigurasi dan menjalankan Framework Functions:

Node.js

Dengan Framework Functions Node.js, Anda dapat menentukan nama fungsi dan jenis tanda tangan sebagai argumen command line atau variabel lingkungan.

Anda juga dapat menentukan nilai ini dalam buildfile package.json dengan menambahkan skrip start dengan argumen CLI yang diperlukan seperti yang ditunjukkan pada contoh di bawah.

"scripts": {
"start": "npx functions-framework --target=YOUR_FUNCTION_NAME [--signature-type=YOUR_SIGNATURE_TYPE]"
}

Hal yang sama dapat dilakukan menggunakan variabel lingkungan:

"scripts": {
"start": "FUNCTION_TARGET=YOUR_FUNCTION_NAME FUNCTION_SIGNATURE_TYPE=YOUR_SIGNATURE_TYPE npx functions-framework"
}

Ganti YOUR_FUNCTION_NAME dengan nama metode fungsi Anda, dan YOUR_SIGNATURE_TYPE (jika ada) dengan jenis tanda tangan fungsi Anda seperti yang ditunjukkan dalam jenis fungsi yang didukung.

Python

Dengan Framework Functions Python, Anda dapat menentukan nama dan jenis tanda tangan fungsi sebagai argumen command line atau variabel lingkungan. Argumen command line harus ditentukan saat Anda menjalankan framework.

Go

Framework Functions Go menggunakan funcframework.RegisterHTTPFunctionContext untuk menentukan target fungsi dan jenis tanda tangan.

Java

Framework Functions Java menerima data konfigurasi dari tiga sumber yang berbeda, dalam urutan prioritas berikut (paling spesifik ke paling tidak spesifik):

  • Argumen command line
  • File Build
  • Variabel lingkungan

Argumen command line

Maven

Anda dapat menentukan fungsi yang ingin dijalankan dengan menambahkan tanda antarmuka command line (CLI) berikut ke perintah mvn:

-Drun.functionTarget=YOUR_FUNCTION_NAME

Anda juga dapat menentukan port target dengan menambahkan flag CLI berikut dengan cara yang sama:

-Drun.port=12345

Gradle

Flag CLI Gradle hampir identik dengan Maven. Satu-satunya perubahan yang dilakukan Gradle adalah menukar -D utama di setiap flag dengan -P seperti yang ditunjukkan dalam contoh berikut:

# Maven version

-Drun.functionTarget=...

# Gradle version

-Prun.functionTarget=...

File Build

Anda juga bisa menetapkan fungsi yang ingin dijalankan di file build project Anda. Meskipun Maven dan Gradle memiliki flag CLI yang serupa, klausa file build-nya memiliki perbedaan yang signifikan.

Maven

File build Maven diberi nama pom.xml. Tambahkan klausa berikut ke file ini untuk menentukan fungsi target:

<plugin>
  <groupId>com.google.cloud.functions</groupId>
  <artifactId>function-maven-plugin</artifactId>
  <version>0.11.0</version>
  <configuration>
    <functionTarget>functions.HelloWorld</functionTarget>
  </configuration>
</plugin>

Ganti <functionTarget> dengan nama class fungsi Anda. Misalnya, fungsi dalam paket functions dengan nama class HelloCloudFunctions akan memiliki nama class functions.HelloCloudFunctions. Ini berhubungan dengan file build induk - pom.xml atau build.gradle.

Gradle

File build Gradle diberi nama build.gradle. Tambahkan klausa berikut ke file ini untuk menentukan fungsi target:

// Register a "runFunction" task to run the function locally
tasks.register("runFunction", JavaExec) {
  main = 'com.google.cloud.functions.invoker.runner.Invoker'
  classpath(configurations.invoker)
  inputs.files(configurations.runtimeClasspath, sourceSets.main.output)
  args(
    '--target', project.findProperty('run.functionTarget') ?: '',
    '--port', project.findProperty('run.port') ?: 8080
  )
  doFirst {
    args('--classpath', files(configurations.runtimeClasspath, sourceSets.main.output).asPath)
  }
}

C#

Jika Anda membuat project menggunakan dotnet new dan salah satu template yang ditentukan sebelumnya, Framework Functions .NET akan otomatis mendeteksi fungsi Anda.

Jika project Anda berisi beberapa fungsi, lihat bagian Menjalankan Framework untuk mengetahui informasi tentang cara menjalankan fungsi tertentu.

Ruby

Dengan Framework Functions Ruby, Anda dapat menentukan nama fungsi dan jenis tanda tangan sebagai argumen command line atau variabel lingkungan. Argumen command line harus ditentukan saat Anda menjalankan framework.

PHP

Dengan Framework Functions PHP, Anda dapat menentukan variabel lingkungan sebagai argumen command line.

Anda juga dapat menentukan nilai ini dalam file build composer.json dengan menambahkan skrip start seperti yang ditunjukkan pada contoh di bawah.

"scripts": {
 "start": [
     "Composer\\Config::disableProcessTimeout",
     "FUNCTION_TARGET=YOUR_FUNCTION_NAME php -S localhost:${PORT:-8080} vendor/bin/router.php"
].
}

Ganti YOUR_FUNCTION_NAME dengan nama fungsi Anda, dan YOUR_SIGNATURE_TYPE (jika ada; tidak disertakan dalam contoh yang ditampilkan di sini).

Menjalankan fungsi

Gunakan perintah berikut untuk menjalankan fungsi Anda dengan Framework Functions. Secara default, fungsi dapat diakses di localhost:8080 kecuali jika Anda menentukan nilai PORT.

Node.js

npm start

Python

Menggunakan argumen command line:

functions-framework --target=YOUR_FUNCTION_NAME

Menggunakan variabel lingkungan:

FUNCTION_TARGET=YOUR_FUNCTION_NAME functions-framework

Ganti YOUR_FUNCTION_NAME dengan nama metode fungsi Anda.

Go

Pertama, buat file cmd/main.go seperti yang dijelaskan di situs Framework Functions untuk Go.

cd cmd
go build
./cmd

Menggunakan variabel lingkungan:

cd cmd
go build
PORT=8080 ./cmd

Java

Maven

Gunakan perintah berikut untuk menjalankan fungsi yang ditentukan di pom.xml:

mvn function:run

Gunakan perintah berikut untuk menjalankan fungsi yang ditetapkan dalam argumen command line:

mvn function:run -Drun.functionTarget=YOUR_FUNCTION_NAME

Gunakan perintah berikut untuk menjalankan fungsi yang ditentukan sebagai variabel lingkungan:

FUNCTION_TARGET=YOUR_FUNCTION_NAME mvn function:run

Ganti YOUR_FUNCTION_NAME dengan nama class fungsi Anda.

Gradle

Gunakan perintah berikut untuk menjalankan fungsi yang ditentukan di build.gradle:

./gradlew runFunction

Gunakan perintah berikut untuk menjalankan fungsi yang ditetapkan dalam argumen command line:

./gradlew runFunction -Prun.functionTarget=YOUR_FUNCTION_NAME

Gunakan perintah berikut untuk menjalankan fungsi yang ditentukan sebagai variabel lingkungan:

FUNCTION_TARGET=YOUR_FUNCTION_NAME ./gradlew runFunction

Ganti YOUR_FUNCTION_NAME dengan nama class fungsi Anda.

C#

Gunakan perintah berikut untuk menjalankan fungsi saat hanya ada satu fungsi dalam project .NET saat ini. Perhatikan bahwa ini adalah struktur default untuk project yang dibuat dengan template.

dotnet run

Jika project .NET Anda berisi beberapa fungsi, gunakan perintah berikut untuk menjalankan fungsi tertentu. Ganti YOUR_FUNCTION_CLASSNAME dengan nama class fungsi Anda, termasuk namespace.

dotnet run YOUR_FUNCTION_CLASSNAME

Jika ingin menjalankan beberapa fungsi secara bersamaan, Anda harus menjalankan beberapa instance Framework Functions. Untuk menghindari konflik antara menjalankan instance framework, setiap instance harus menggunakan nilai PORT yang berbeda. Perintah berikut menunjukkan cara menjalankan fungsi dengan nilai PORT 8080.

Menggunakan argumen command line:

dotnet run --target YOUR_FUNCTION_CLASSNAME --port 8080

Menggunakan variabel lingkungan:

FUNCTION_TARGET=YOUR_FUNCTION_CLASSNAME PORT=8080 dotnet run

Ruby

Menggunakan argumen command line:

bundle exec functions-framework-ruby --target YOUR_FUNCTION_NAME

Menggunakan variabel lingkungan:

FUNCTION_TARGET=YOUR_FUNCTION_NAME bundle exec functions-framework-ruby

Ganti YOUR_FUNCTION_NAME dengan nama metode fungsi Anda.

PHP

export FUNCTION_TARGET=YOUR_FUNCTION_NAME
php -S localhost:8080 vendor/bin/router.php

Ganti YOUR_FUNCTION_NAME dengan nama fungsi Anda.

Memanggil fungsi yang berjalan secara lokal

Latihan di bagian ini mengasumsikan bahwa Anda telah menyiapkan fungsi yang berjalan secara lokal di localhost menggunakan Functions Framework.

Anda dapat memicu fungsi yang berjalan secara lokal dengan mengiriminya permintaan HTTP yang dirutekan menggunakan proses inferensi lokal.

Fungsi HTTP

Saat Anda menguji fungsi HTTP dari lingkungan pengembangan, fungsi HTTP biasanya akan memproses permintaan di localhost:8080. Antarmuka ini hanya dapat diakses dari mesin atau VM tempat fungsi Anda berjalan; permintaan yang dikirim dari sistem lain tidak dapat mencapainya. Karena alasan ini, Anda harus mengeluarkan permintaan HTTP dari sistem yang sama dengan tempat fungsi Anda berjalan. Dalam contoh berikut, jika fungsi Anda memproses port selain 8080, ganti 8080 dalam contoh dengan nomor port untuk fungsi Anda.

Menguji fungsi HTTP dengan Cloud Shell

Jika Anda menggunakan Cloud Shell untuk mem-build dan menguji fungsi, mulai fungsi secara lokal di jendela terminal Cloud Shell, lalu keluarkan permintaan pemicu HTTP dari browser atau instance curl sebagai berikut:

Browser

Klik ikon Tombol Web Preview di toolbar Cloud Shell dan pilih port 8080 atau Ubah port untuk memilih port lain. Tindakan ini akan membuka jendela browser di sistem yang benar dan mengirimkan permintaan GET ke port yang ditunjukkan.

Curl

Untuk mengontrol format permintaan HTTP atau melihat balasan yang tidak berformat, gunakan curl:

  1. Klik ikon + pada panel menu Cloud Shell untuk membuka jendela terminal baru di sistem yang sama dengan tempat fungsi Anda berjalan.
  2. Dari dalam jendela tersebut, jalankan perintah curl untuk memicu fungsi Anda. Contoh:

    curl localhost:8080
    

Menguji fungsi HTTP di server desktop

Jika Anda mem-build dan menjalankan fungsi di sistem desktop lokal, pertama-tama mulai fungsi Anda secara lokal, lalu keluarkan permintaan pemicu HTTP dari browser atau instance curl sebagai berikut:

Browser

Buka tab atau jendela browser baru, lalu ketik http://localhost:8080 di kolom URL browser. Tindakan ini akan membuka jendela browser ke localhost:8080 di server desktop untuk memicu fungsi Anda.

Curl

Buka jendela terminal baru di desktop lokal Anda, lalu jalankan perintah curl di jendela tersebut untuk memicu fungsi Anda. Contoh:

 curl localhost:8080

Tindakan ini menjalankan perintah curl yang ditentukan untuk memicu fungsi Anda dan menampilkan respons yang tidak diformat.

Fungsi CloudEvent

Anda dapat mengirim contoh peristiwa ke fungsi CloudEvent menggunakan curl. Permintaan curl berikut menunjukkan cara mengirim contoh peristiwa Pub/Sub dan Cloud Storage ke fungsi CloudEvent yang berjalan di localhost:8080.

Pub/Sub

curl localhost:8080 \
  -X POST \
  -H "Content-Type: application/json" \
  -H "ce-id: 123451234512345" \
  -H "ce-specversion: 1.0" \
  -H "ce-time: 2020-01-02T12:34:56.789Z" \
  -H "ce-type: google.cloud.pubsub.topic.v1.messagePublished" \
  -H "ce-source: //pubsub.googleapis.com/projects/MY-PROJECT/topics/MY-TOPIC" \
  -d '{
        "message": {
          "data": "d29ybGQ=",
          "attributes": {
             "attr1":"attr1-value"
          }
        },
        "subscription": "projects/MY-PROJECT/subscriptions/MY-SUB"
      }'
    

Cloud Storage

curl localhost:8080 \
  -X POST \
  -H "Content-Type: application/json" \
  -H "ce-id: 123451234512345" \
  -H "ce-specversion: 1.0" \
  -H "ce-time: 2020-01-02T12:34:56.789Z" \
  -H "ce-type: google.cloud.storage.object.v1.finalized" \
  -H "ce-source: //storage.googleapis.com/projects/_/buckets/MY-BUCKET-NAME" \
  -H "ce-subject: objects/MY_FILE.txt" \
  -d '{
        "bucket": "MY_BUCKET",
        "contentType": "text/plain",
        "kind": "storage#object",
        "md5Hash": "...",
        "metageneration": "1",
        "name": "MY_FILE.txt",
        "size": "352",
        "storageClass": "MULTI_REGIONAL",
        "timeCreated": "2020-04-23T07:38:57.230Z",
        "timeStorageClassUpdated": "2020-04-23T07:38:57.230Z",
        "updated": "2020-04-23T07:38:57.230Z"
      }'