Funções: Chamar uma Função usando o API Gateway

Neste tutorial, você usa o Oracle Functions para processar dados transmitidos do Oracle API Gateway. Você cria uma função Python que usa o contexto de runtime para extrair informações HTTP passadas em uma solicitação.

As principais tarefas incluem:

  • Reúna as informações necessárias.
  • Crie um aplicativo para sua função.
  • Crie uma função "Hello World!".
  • Converta sua função para processar dados de contexto de runtime.
  • Implemente e teste sua função.
  • Criar um Gateway de API para sua função
  • Chame sua função pela internet usando seu Gateway de API.
As imagens mostram os componentes do OCI usados para executar funções Oracle.

Para obter informações adicionais, consulte:

Antes de Começar

Para executar este tutorial com sucesso, você precisa ter o seguinte:

Requisitos da Conta do OCI
Requisitos de Software

CLI da Oracle

Oracle Cloud Shell

  • Se você usar o Cloud Shell, a lista anterior de software já estará instalada.

1. Reunir as Informações Necessárias

Recolha todas as informações necessárias para concluir o tutorial. Copie as informações a seguir no seu bloco de notas.

Obter Informações do Compartimento

Para criar um compartimento, consulte Criar um compartimento. Depois que seu compartimento for criado, salve o OCID e o nome do compartimento.

Para obter o OCID do compartimento de um compartimento existente:

  1. Abra o menu de navegação e clique em Identidade e Segurança. Em Identidade, clique em Compartimentos.
  2. Selecione seu compartimento.
  3. Clique no link Copiar do campo OCID.

Salve o OCID e o nome do compartimento.

Informações Coletadas

Verifique se você tem as seguintes informações anotadas para o tutorial.

  • Nome do Compartimento: <your-compartment-name>

    Exemplo: my-compartment

  • ID do Compartimento: <your-compartment-OCID>

    Exemplo: ocid1.compartment.oc1.aaaaaaa...

  • Nome da VCN: <your-vcn-name>

    Exemplo: my-vcn

    Abra o menu de navegação e clique em Rede; em seguida, clique em Redes Virtuais na Nuvem. Na lista de redes, selecione sua VCN.

  • Nome da Sub-rede Pública da VCN: <Public-Subnet-your-vcn-name>

    Exemplo: Public-Subnet-my-vcn

    Abra o menu de navegação e clique em Rede; em seguida, clique em Redes Virtuais na Nuvem. Na lista de redes, selecione sua VCN.

2. Executar Configuração Obrigatória

Execute toda a configuração necessária para o tutorial.

Criar Aplicativo Functions

Para criar um aplicativo, siga estas etapas.

  1. Abra o menu de navegação e clique em Serviços do Desenvolvedor. Em Funções, clique em Aplicativos.
  2. Selecione seu compartimento na lista drop-down Compartimento.
  3. Clique em Criar Aplicativo.
  4. Preencha os dados do form.
    • Nome: <your-app-name>
    • VCN: <your-vcn-name>
    • Sub-redes: <Public-Subnet-your-vcn-name>
  5. Clique em Criar.

Seu aplicativo foi criado.

Configurar Regra de Entrada para HTTPS
  1. Abra o menu de navegação e clique em Rede; em seguida, clique em Redes Virtuais na Nuvem.
  2. Clique no nome da VCN que você usou para seu aplicativo Oracle Functions.
  3. Com sua nova VCN exibida, clique no link de sub-rede Pública.

    As informações da sub-rede pública são exibidas com as Listas de Segurança na parte inferior da página.

  4. Clique no link Lista de Segurança Padrão ou no link da lista de segurança apropriado.

    As Regras de Entrada padrão da sua VCN são exibidas.

  5. Clique em Adicionar Regras de Entrada.

    Uma caixa de diálogo Adicionar Regras de Entrada é exibida.

  6. Preencha a regra de entrada com as informações a seguir. Depois que todos os dados forem inseridos, clique em Adicionar Regras de Entrada

    Preencha a regra de entrada da seguinte forma:

    • Sem monitoramento de estado: Marcado
    • Tipo de Origem: CIDR
    • CIDR de Origem: 0.0.0.0/0
    • Protocolo IP: TCP
    • Intervalo de portas de origem: (leave-blank)
    • Faixa de Portas de Destino: 443
    • Descrição: VCN para aplicativos

    Depois que você clicar em Adicionar Regra de Entrada, as conexões HTTPS serão permitidas à sua sub-rede pública.

Política de Configuração para Acesso do API Gateway a Funções

Em seguida, configure uma política que permita que o API Gateway chame funções.

Primeiro, crie um Grupo Dinâmico para o API Gateway.

  1. Abra o menu de navegação e clique em Identidade e Segurança. Em Identidade, clique em Grupos Dinâmicos.
  2. Clique em Criar Grupo Dinâmico.
  3. Preencha as informações a seguir para definir seu grupo dinâmico.
    • Nome: <name-for-your-dynamic-group>
    • Em Regras de Correspondência, use a Regra 1: <the-rule-text>

    Aqui está o nome da amostra e a regra que você precisa preencher. Substitua <your-compartment-OCID> pelo respectivo valor.

    • Nome: api-gtw-func-dynamic-group
    • Em Regras de Correspondência, use a Regra 1: ALL {resource.type = 'ApiGateway', resource.compartment.id = '<your-compartment-OCID>'}
  4. Clique em Criar.

Agora crie a política para o API Gateway.

  1. Abra o menu de navegação e clique em Identidade e Segurança. Em Identidade, clique em Políticas.
  2. Clique em Criar Política.
  3. Para definir sua política, preencha as informações a seguir.
    • Nome: <name-for-your-policy>
    • Descrição: <description-for policy>
    • Compartimento: <name-of-functions-compartment>

    Para a seção Criador de Política:

    • Clique em Mostrar editor manual.
    • Informe a política na caixa de texto, por exemplo:
      Allow dynamic-group api-gtw-func-dynamic-group to use functions-family in compartment <your-compartment-name>
      Observação

      O último parâmetro é o nome do compartimento, não o OCID do compartimento.
  4. Clique em Criar.

Você criou uma política para permitir que o API Gateway use Funções.

Criar Função Python "Hello World"
  1. Abra um terminal.
  2. Crie um diretório para armazenar suas funções e passe para esse diretório.
    mkdir my-dir-name
    cd my-dir-name                        
                         
  3. Crie uma função "Hello World" do Python com Fn.
    fn init --runtime python my-func-name

    Esse comando cria um diretório chamado my-func-name com a função e os arquivos de configuração nele.

  4. Passe para o diretório.
  5. Implante a função.
    fn -v deploy --app your-app-name

    Várias mensagens são exibidas à medida que as imagens do Docker são criadas, enviadas para o OCIR e por fim implantadas no Oracle Functions.

  6. Chame a função.
    fn invoke your-app-name my-func-name

    Retorna: {"message": "Hello World"}

  7. Chame a função com um parâmetro.
    echo -n '{"name":"Bob"}' | fn invoke your-app-name my-func-name

    Retorna: {"message": "Hello Bob"}

3. Criar um Gateway de API

Para chamar sua função, crie um Gateway de API.

Criar o Gateway de API

Para criar um Gateway de API:

  1. Abra o menu de navegação e clique em Serviços do Desenvolvedor. Em Gerenciamento de API, clique em Gateways.
  2. Selecione seu compartimento na lista drop-down Compartimento.
  3. Clique em Criar Gateway
  4. Preencha as informações a seguir para definir seu Gateway de API.
    • Nome: <your-gateway-name>
    • Tipo: <Public>
    • Compartimento: <your-compartment-name>
    • Rede Virtual na Nuvem em <your-vcn-name>: <select-your-vcn>
    • Sub-rede em <your-compartment-name: <your-public-subnet-name>
  5. Clique em Criar. Aguarde alguns minutos para que o seu Gateway de API seja criado.
Criar uma Implantação de API para seu Gateway

Em seguida, crie uma implantação para seu Gateway de API.

  1. Clique em Implantações na seção Recursos do lado esquerdo da tela.
  2. Clique em Criar Implantação.
  3. Certifique-se de que Totalmente Novo esteja selecionado para o tipo de implantação.
  4. Para definir sua implantação, preencha a seção Informações Básicas.
    • Nome: <your-deployment-name>
    • Prefixo do Caminho (exemplo): /v1
    • Compartimento: <your-compartment-name>
    • Políticas de Solicitação de API: Utilizar valores padrão
    • Políticas de Registro em Log de API: Utilizar valor padrão de Informações
  5. Clique em Próximo. A caixa de diálogo Rotas é exibida com a opção Rota 1 selecionada.
  6. Para definir sua rota, preencha a seção Rota 1.
    • Campo: <your-route-path>

      Exemplo: /http-info

    • Métodos: GET POST
    • Tipo: Oracle Functions
    • Aplicativo em <your-compartment-name>: Selecione o aplicativo Functions criado.
    • Nome da Função: Selecione a função que você criou na seção de configuração.
  7. Clique em Próximo. A caixa de diálogo Revisar é exibida, resumindo as opções feitas.
  8. Clique em Criar. Sua implantação é criada.
  9. Clique no link Implantações do seu gateway. Copie o ponto final base da implantação criada.

    Por exemplo: https://aaaaa.apigateway.us-ashburn-X.oci.customer-oic.com/v1

Testar seu Gateway de API

Com o Gateway de API e a implantação criados, agora você pode testar a instalação. Crie um script simples para o comando curl. Para criar o URL para curl, adicione seu caminho de implantação ao seu ponto final.

  1. Crie o arquivo de script: touch gtw01.sh && chmod 755 gtw01.sh
  2. Adicione o comando curl ao arquivo de script:
    #!/bin/bash
    curl <your-api-gateway-endpoint>/http-info
  3. O comando retorna: {"message":"Hello World"}

Você conectou seu Gateway de API a uma função Python com texto padronizado. Em seguida, você atualiza sua função Python para exibir informações transmitidas em uma solicitação HTTP.

4. Atualizar Função para Acessar Dados HTTP e de Função

Em seguida, modifique a função Python de texto padronizado para acessar o contexto de runtime e exibir informações HTTP.

Verificar Código Python Inicial

Se você observar a função de texto padronizado, sua função Python será semelhante a esta.

import io
import json
import logging

from fdk import response


def handler(ctx, data: io.BytesIO = None):
    name = "World"
    try:
        body = json.loads(data.getvalue())
        name = body.get("name")
    except (Exception, ValueError) as ex:
        logging.getLogger().info('error parsing json payload: ' + str(ex))
    
    logging.getLogger().info("Inside Python Hello World function")
    return response.Response(
       ctx, response_data=json.dumps(
           {"message": "Hello {0}".format(name)}),
       headers={"Content-Type": "application/json"}
    )

Usando esse código como ponto de partida, as seções que vêm depois convertem a função em uma função Python que retorna dados HTTP e de configuração.

Atualizar Pacotes Necessários

Primeiro, atualize a função dos pacotes necessários.

  1. Atualize o arquivo requirements.txt do pacote oci.
    fdk
    oci                    
                    
  2. Atualize as instruções import em func.py dos pacotes necessários para os recursos HTTP:
    import io
    import json
    import oci
    import logging
    from urllib.parse import urlparse, parse_qs                    
                    

    O pacote oci é necessário para algumas solicitações de contexto. Os pacotes urlparse, parse_qs são usados para parsing.

Adicionar Informações da Solicitação HTTP

Primeiro, remova o corpo principal da função. O método response e o código relacionado são adicionados de volta à medida que avançamos.

import io
import json
import oci
import logging
from urllib.parse import urlparse, parse_qs  
                
from fdk import response

def handler(ctx, data: io.BytesIO = None):                
            

Em seguida, adicione código para exibir informações HTTP na resposta. Veja a seguir o código com comentários.

import io
import json
import oci
import logging
from urllib.parse import urlparse, parse_qs  
                
from fdk import response

def handler(ctx, data: io.BytesIO = None):
    logging.getLogger().info("HTTP function start")
    
    resp = {}
    
    # retrieving the request headers
    headers = ctx.Headers()
    logging.getLogger().info("Headers: " + json.dumps(headers))
    resp["Headers"] = headers
    
    # retrieving the request body, e.g. {"key1":"value"}
    try:
        requestbody_str = data.getvalue().decode('UTF-8')
        if requestbody_str:
            resp["Request body"] = json.loads(requestbody_str)
        else:
            resp["Request body"] = {}
    except Exception as ex:
        print('ERROR: The request body is not JSON', ex, flush=True)
        raise
    
    # retrieving the request URL, e.g. "/v1/http-info"
    requesturl = ctx.RequestURL()
    logging.getLogger().info("Request URL: " + json.dumps(requesturl))
    resp["Request URL"] = requesturl
    
    # retrieving query string from the request URL, e.g. {"param1":["value"]}
    parsed_url = urlparse(requesturl)
    resp["Query String"] = parse_qs(parsed_url.query)
    logging.getLogger().info("Query string: " + json.dumps(resp["Query String"]))
    
    # retrieving the request method, e.g. "POST", "GET"...
    method = ctx.Method()
    if method:
        logging.getLogger().info("Request Method: " + method)
    resp["Request Method"] = method
    else:
        logging.getLogger().info("No Request Method")
        resp["Request Method"] = None
  • A função handler recebe informações do sistema sobre a solicitação atual por meio dos parâmetros ctx e data.
  • Todos os dados são adicionados ao dicionário resp, que é retornado na resposta.
  • Observe que o contexto de runtime da função (ctx) contém grande parte dos dados HTTP passados de uma solicitação, incluindo: cabeçalhos, URL da solicitação e método.
  • O parâmetro data retorna o corpo da solicitação.
Adicionar à Resposta os Dados Relacionados à Função

Em seguida, recupere os dados relacionados do Oracle Functions no contexto e, em seguida, retorne uma resposta. Seguem-se os comentários.


    # retrieving the function configuration
    resp["Configuration"] = dict(ctx.Config())
    logging.getLogger().info("Configuration: " + json.dumps(resp["Configuration"]))
    
    # retrieving the Application ID, e.g. "ocid1.fnapp.oc1.phx.aaaaxxxx"
    appid = ctx.AppID()
    logging.getLogger().info("AppID: " + appid)
    resp["AppID"] = appid
    
    # retrieving the Function ID, e.g. "ocid1.fnfunc.oc1.phx.aaaaxxxxx"
    fnid = ctx.FnID()
    logging.getLogger().info("FnID: " + fnid)
    resp["FnID"] = fnid
    
    # retrieving the Function call ID, e.g. "01E9FE6JBW1BT0C68ZJ003KR1Q"
    callid = ctx.CallID()
    logging.getLogger().info("CallID: " + callid)
    resp["CallID"] = callid
    
    # retrieving the Function format, e.g. "http-stream"
    fnformat = ctx.Format()
    logging.getLogger().info("Format: " + fnformat)
    resp["Format"] = fnformat
    
    # retrieving the Function deadline, e.g. "2020-05-29T05:24:46Z"
    deadline = ctx.Deadline()
    logging.getLogger().info("Deadline: " + deadline)
    resp["Deadline"] = deadline
    
    logging.getLogger().info("function handler end")
    return response.Response(
        ctx, 
        response_data=json.dumps(resp),
        headers={"Content-Type": "application/json"}
    )

Observe que todos os dados relacionados a Funções são recuperados do objeto ctx, incluindo: AppID, FnID e Format.

Verificar Função Final

Este é o código da função final.

import io
import json
import oci
import logging
from urllib.parse import urlparse, parse_qs

from fdk import response

def handler(ctx, data: io.BytesIO = None):
    logging.getLogger().info("HTTP function start")
    
    resp = {}
    
    # retrieving the request headers
    headers = ctx.Headers()
    logging.getLogger().info("Headers: " + json.dumps(headers))
    resp["Headers"] = headers
    
    # retrieving the request body, e.g. {"key1":"value"}
    try:
        requestbody_str = data.getvalue().decode('UTF-8')
        if requestbody_str:
            resp["Request body"] = json.loads(requestbody_str)
        else:
            resp["Request body"] = {}
    except Exception as ex:
        print('ERROR: The request body is not JSON', ex, flush=True)
        raise
    
    # retrieving the request URL, e.g. "/v1/http-info"
    requesturl = ctx.RequestURL()
    logging.getLogger().info("Request URL: " + json.dumps(requesturl))
    resp["Request URL"] = requesturl
    
    # retrieving query string from the request URL, e.g. {"param1":["value"]}
    parsed_url = urlparse(requesturl)
    resp["Query String"] = parse_qs(parsed_url.query)
    logging.getLogger().info("Query string: " + json.dumps(resp["Query String"]))
    
    # retrieving the request method, e.g. "POST", "GET"...
    method = ctx.Method()
    if method:
        logging.getLogger().info("Request Method: " + method)
        resp["Request Method"] = method
    else:
        logging.getLogger().info("No Request Method")
        resp["Request Method"] = None
    
    # retrieving the function configuration
    resp["Configuration"] = dict(ctx.Config())
    logging.getLogger().info("Configuration: " + json.dumps(resp["Configuration"]))
    
    # retrieving the Application ID, e.g. "ocid1.fnapp.oc1.phx.aaaaxxxx"
    appid = ctx.AppID()
    logging.getLogger().info("AppID: " + appid)
    resp["AppID"] = appid
    
    # retrieving the Function ID, e.g. "ocid1.fnfunc.oc1.phx.aaaaxxxxx"
    fnid = ctx.FnID()
    logging.getLogger().info("FnID: " + fnid)
    resp["FnID"] = fnid
    
    # retrieving the Function call ID, e.g. "01E9FE6JBW1BT0C68ZJ003KR1Q"
    callid = ctx.CallID()
    logging.getLogger().info("CallID: " + callid)
    resp["CallID"] = callid
    
    # retrieving the Function format, e.g. "http-stream"
    fnformat = ctx.Format()
    logging.getLogger().info("Format: " + fnformat)
    resp["Format"] = fnformat
    
    # retrieving the Function deadline, e.g. "2020-05-29T05:24:46Z"
    deadline = ctx.Deadline()
    logging.getLogger().info("Deadline: " + deadline)
    resp["Deadline"] = deadline
    
    logging.getLogger().info("function handler end")
    return response.Response(
        ctx, 
        response_data=json.dumps(resp),
        headers={"Content-Type": "application/json"}
    )         
            

Agora você está pronto para testar sua função novamente e ver os resultados.

Criar Variáveis de Configuração de Funções

O Oracle Functions permite que você armazene dados de configuração no seu contexto que está disponível em sua solicitação. Os dados de configuração podem ser armazenados em um aplicativo ou em uma função. Os comandos a seguir armazenam informações do banco de dados no contexto do aplicativo.

  • fn config app <your-app-name> DB-NAME your-db-name
  • fn config app <your-app-name> DB-USER your-user-name

Para obter mais informações, consulte o tutorial do Fn Project no contexto de runtime.

Testar sua Função
  1. Reimplante a função atualizada.
  2. Chame a função para garantir que ela esteja funcionando.
  3. Execute seu script novamente. Para obter uma saída JSON formatada, use o utilitário jq que está incluído no shell da nuvem. Se você estiver usando a CLI, instale jq na sua máquina local.
    gtw01.sh | jq

    Os dados retornados são semelhantes a:

    {
        "Headers": {
        "host": [
        "localhost",
        "ctr6kqbjpza5tjnzafaqpqif5i.apigateway.us-phoenix-1.oci.customer-oci.com"
        ],
        "user-agent": [
        "lua-resty-http/0.14 (Lua) ngx_lua/10015",
        "curl/7.64.1"
        ],
        "transfer-encoding": "chunked",
        "content-type": [
        "application/octet-stream",
        "application/octet-stream"
        ],
        "date": "Thu, 10 Dec 2020 01:35:43 GMT",
        "fn-call-id": "01ES54MAKK1BT0H50ZJ00NGX00",
        "fn-deadline": "2020-12-10T01:36:13Z",
        "accept": "*/*",
        "cdn-loop": "iQPgvPk4HZ74L-PRJqYw7A",
        "forwarded": "for=73.34.74.159",
        "x-forwarded-for": "73.34.74.159",
        "x-real-ip": "73.34.74.159",
        "fn-http-method": "GET",
        "fn-http-request-url": "/v1/http-info",
        "fn-intent": "httprequest",
        "fn-invoke-type": "sync",
        "oci-subject-id": "ocid1.apigateway.oc1.phx.0000000000000000000000000000000000000000000000000000",
        "oci-subject-tenancy-id": "ocid1.tenancy.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
        "oci-subject-type": "resource",
        "opc-request-id": "/A79EAB4A240E93EB226366B190A494BC/01ES54MAK21BT0H50ZJ00NGWZZ",
        "x-content-sha256": "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
        "accept-encoding": "gzip"
        },
        "Configuration": {
        "PATH": "/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "HOSTNAME": "7747cc436a14",
        "FN_LISTENER": "unix:/tmp/iofs/lsnr.sock",
        "FN_CPUS": "125m",
        "FN_LOGFRAME_NAME": "01ES54E5RN00000000000001JF",
        "FN_LOGFRAME_HDR": "Opc-Request-Id",
        "FN_FORMAT": "http-stream",
        "DB-NAME": "your-db-name",
        "DB-USER": "your-user-name",
        "FN_APP_ID": "ocid1.fnapp.oc1.phx.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
        "FN_FN_ID": "ocid1.fnfunc.oc1.phx.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
        "FN_MEMORY": "256",
        "FN_TYPE": "sync",
        "OCI_RESOURCE_PRINCIPAL_RPST": "/.oci-credentials/rpst",
        "OCI_RESOURCE_PRINCIPAL_PRIVATE_PEM": "/.oci-credentials/private.pem",
        "OCI_RESOURCE_PRINCIPAL_VERSION": "2.2",
        "OCI_RESOURCE_PRINCIPAL_REGION": "us-phoenix-1",
        "OCI_REGION_METADATA": "{\"realmDomainComponent\":\"oraclecloud.com\",\"realmKey\":\"oc1\",\"regionIdentifier\":\"us-phoenix-1\",\"regionKey\":\"PHX\"}",
        "LANG": "C.UTF-8",
        "GPG_KEY": "E3FF2839C048B25C084DEBE9B26995E310250568",
        "PYTHON_VERSION": "3.8.5",
        "PYTHON_PIP_VERSION": "20.2.2",
        "PYTHON_GET_PIP_URL": "https://github.com/pypa/get-pip/raw/5578af97f8b2b466f4cdbebe18a3ba2d48ad1434/get-pip.py",
        "PYTHON_GET_PIP_SHA256": "d4d62a0850fe0c2e6325b2cc20d818c580563de5a2038f917e3cb0e25280b4d1",
        "PYTHONPATH": "/function:/python",
        "HOME": "/home/fn"
        },
        "Request body": {},
        "Request URL": "/v1/http-info",
        "Query String": {},
        "Request Method": "GET",
        "AppID": "ocid1.fnapp.oc1.phx.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
        "FnID": "ocid1.fnfunc.oc1.phx.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
        "CallID": "01ES54MAKK1BT0H50ZJ00NGX00",
        "Format": "http-stream",
        "Deadline": "2020-12-10T01:36:13Z"
    }
                    
                

    Observe todos os dados de Funções retornados na segunda metade da resposta, incluindo: AppID, FnID e Format. Além disso, na seção Configuration, você vê as variáveis de ambiente geradas por Funções, como FN_FORMAT e as variáveis de configuração: DB-NAME e DB-USER.

  4. Atualize seu script para transmitir cabeçalhos e dados POST para o script.
    /bin/bash
    curl -X POST --header "X-MyHeader1: headerValue" -d '{"key1":"value"}' https://aaaaa.apigateway.us-ashburn-X.oci.customer-oic.com/v1/http-info

    A saída do script é semelhante a:

    {
        "Headers": {
        "host": [
        "localhost",
        "ctr6kqbjpza5tjnzafaqpqif5i.apigateway.us-phoenix-1.oci.customer-oci.com"
        ],
        "user-agent": [
        "lua-resty-http/0.14 (Lua) ngx_lua/10015",
        "curl/7.64.1"
        ],
        "transfer-encoding": "chunked",
        "content-type": [
        "application/x-www-form-urlencoded",
        "application/x-www-form-urlencoded"
        ],
        "date": "Thu, 10 Dec 2020 17:05:14 GMT",
        "fn-call-id": "000000000000000000000000000",
        "fn-deadline": "2020-12-10T17:05:44Z",
        "accept": "*/*",
        "cdn-loop": "iQPgvPk4HZ74L-PRJqYw7A",
        "content-length": "16",
        "forwarded": "for=73.34.74.159",
        "x-forwarded-for": "73.34.74.159",
        "x-myheader1": "headerValue",
        "x-real-ip": "73.34.74.159",
        "fn-http-method": "POST",
        "fn-http-request-url": "/v1/http-info",
        "fn-intent": "httprequest",
        "fn-invoke-type": "sync",
        "oci-subject-id": "ocid1.apigateway.oc1.phx.0000000000000000000000000000000000000000000000000000",
        "oci-subject-tenancy-id": "ocid1.tenancy.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
        "oci-subject-type": "resource",
        "opc-request-id": "/32DE93ED4A72B932E62460362A24DA40/01ES6STAH91BT0G48ZJ00J07ZT",
        "x-content-sha256": "xMAO2Qww/EVSr1CsSxtHsZu9VicSjb2EMvMmDMjZcVA=",
        "accept-encoding": "gzip"
        },
        "Configuration": {
        "PATH": "/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "HOSTNAME": "1afb03686740",
        "FN_LISTENER": "unix:/tmp/iofs/lsnr.sock",
        "FN_CPUS": "125m",
        "FN_APP_ID": "ocid1.fnapp.oc1.phx.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
        "FN_FN_ID": "ocid1.fnfunc.oc1.phx.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
        "FN_MEMORY": "256",
        "FN_TYPE": "sync",
        "FN_FORMAT": "http-stream",
        "DB-NAME": "your-db-name",
        "DB-USER": "your-user-name",
        "FN_LOGFRAME_NAME": "01ES6SSJY600000000000000BF",
        "FN_LOGFRAME_HDR": "Opc-Request-Id",
        "OCI_RESOURCE_PRINCIPAL_RPST": "/.oci-credentials/rpst",
        "OCI_RESOURCE_PRINCIPAL_PRIVATE_PEM": "/.oci-credentials/private.pem",
        "OCI_RESOURCE_PRINCIPAL_VERSION": "2.2",
        "OCI_RESOURCE_PRINCIPAL_REGION": "us-phoenix-1",
        "OCI_REGION_METADATA": "{\"realmDomainComponent\":\"oraclecloud.com\",\"realmKey\":\"oc1\",\"regionIdentifier\":\"us-phoenix-1\",\"regionKey\":\"PHX\"}",
        "LANG": "C.UTF-8",
        "GPG_KEY": "E3FF2839C048B25C084DEBE9B26995E310250568",
        "PYTHON_VERSION": "3.8.5",
        "PYTHON_PIP_VERSION": "20.2.2",
        "PYTHON_GET_PIP_URL": "https://github.com/pypa/get-pip/raw/5578af97f8b2b466f4cdbebe18a3ba2d48ad1434/get-pip.py",
        "PYTHON_GET_PIP_SHA256": "d4d62a0850fe0c2e6325b2cc20d818c580563de5a2038f917e3cb0e25280b4d1",
        "PYTHONPATH": "/function:/python",
        "HOME": "/home/fn"
        },
        "Request body": {
        "key1": "value"
        },
        "Request URL": "/v1/http-info",
        "Query String": {},
        "Request Method": "POST",
        "AppID": "ocid1.fnapp.oc1.phx.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
        "FnID": "ocid1.fnfunc.oc1.phx.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
        "CallID": "000000000000000000000000000",
        "Format": "http-stream",
        "Deadline": "2020-12-10T17:05:44Z"
    }

    Observe os dados do cabeçalho e do corpo da solicitação. Os dados JSON de chave/valor são listados na seção "Corpo da Solicitação". Você pode fazer download do código-fonte completo para a função no site Amostras do Oracle Function aqui.

Parabéns, você converteu a função Python do texto padronizado em uma nova função que retorna dados HTTP e do Oracle Function. A função demonstra como os dados podem ser passados para o Gateway de API e processados em uma função.