Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

함수에서 웹훅 호출

TSv1 함수는 가져온 소스의 웹훅 바인딩으로 외부 시스템을 호출할 수 있습니다. TSv2와 Python은 웹훅을 웹훅 함수로 게시한 뒤 저장소로 가져와 OSDK로 호출하는 경로를 사용합니다. outbound application 기반 인증도 지원합니다.

먼저 소스와 웹훅을 만들고 함수 저장소를 준비해야 합니다.

소스 가져오기

REST API 소스의 Enable code imports에서 코드 가져오기를 허용합니다. 함수의 모든 사용 위치에서 내보내기 보안 표지를 검증할 수는 없으므로 Enable exports에서 보안 표지 검증 없는 내보내기도 허용하도록 구성해야 합니다. 이 경로의 데이터 전달과 실행 권한을 함께 검토해야 합니다.

Resource imports의 Add > Sources에서 기반 소스를 가져옵니다. 이 대화상자에는 API 이름이 있는 소스만 가져올 수 있습니다.

소스를 웹훅에만 사용하는 함수 저장소는 소스 개요의 가져온 저장소 목록에 표시되지 않습니다. Python transforms나 Compute modules의 소스 가져오기와 다른 동작이므로 그 목록만으로 함수 소비자를 모두 조사할 수는 없습니다.

코드 바인딩 오류

소스 API 이름이 MyDictionarySource이면 @foundry/external-systems/sources에서 해당 심벌을 가져옵니다.

Cannot find module '@foundry/external-systems' or its corresponding type declarations.가 발생하면 functions-typescript/functions.json의 enableExternalSystems를 true로 설정하고 커밋해야 필요한 패키지를 설치합니다. 기존 설정에 이 항목을 추가하고 나머지는 유지합니다.

{
  "enableExternalSystems": true
}

여러 사전 요청과 부분 실패

다음 예제는 읽기 전용 GetDefinition 웹훅을 사용합니다. 입력은 wordToDefine 문자열이고 출력에는 dictionary_definitions, 각 항목의 meanings, partOfSpeech와 definitions 안의 definition이 정의되어 있어야 합니다. 예상 필드가 있는 Record 출력으로 구성합니다.

웹훅이 외부 상태를 바꾸지 않으므로 Query를 사용합니다. 함수는 단어마다 실제 요청을 병렬 실행하고 성공한 정의와 오류 상태를 함께 반환합니다.

import { Query, isOk } from "@foundry/functions-api";
import { MyDictionarySource } from "@foundry/external-systems/sources";

interface Definition {
    partOfSpeech: string;
    definition: string;
}

interface WordResult {
    word: string;
    ok: boolean;
    definitions: Definition[];
    errorName?: string;
    errorMessage?: string;
}

function explainError(name: string): string {
    switch (name) {
        case "WebhookExecutionFailedToStart": return "외부 요청을 시작하지 못했습니다.";
        case "WebhookExecutionTimedOut": return "시작한 외부 요청의 응답이 시간 안에 오지 않았습니다.";
        case "RemoteRestApiReturnedError": return "외부 REST API가 오류를 반환했습니다.";
        case "RemoteApiReturnedError": return "외부 API가 오류를 반환했습니다.";
        case "ParsingResponseFailed": return "외부 호출은 성공했지만 응답을 해석하지 못했습니다.";
        case "ServerError": return "웹훅 서비스나 커넥터 내부에서 오류가 발생했습니다.";
        case "UnknownError": return "오류의 발생 서비스를 식별하지 못했습니다.";
        default: return `새 웹훅 오류가 반환되었습니다: ${name}`;
    }
}

export class DictionaryFunctions {
    @Query()
    public async defineWords(words: string[]): Promise<WordResult[]> {
        const responses = await Promise.all(words.map(word =>
            MyDictionarySource.webhooks.GetDefinition.call({ wordToDefine: word })
        ));
        return responses.map((result, index) => {
            const word = words[index]!;
            if (!isOk(result)) {
                return {
                    word,
                    ok: false,
                    definitions: [],
                    errorName: result.error.name,
                    errorMessage: explainError(result.error.name),
                };
            }
            const definitions: Definition[] = [];
            for (const entry of result.value.output.dictionary_definitions) {
                for (const meaning of entry.meanings) {
                    for (const definition of meaning.definitions) {
                        definitions.push({
                            partOfSpeech: meaning.partOfSpeech,
                            definition: definition.definition,
                        });
                    }
                }
            }
            return { word, ok: true, definitions };
        });
    }
}

클래스를 index.ts에서 내보냅니다. 입력 예시는 ["tuba", "cool"]과 ["asdf", "shire"]입니다. 일부 단어의 웹훅이 오류 결과를 반환해도 다른 단어의 성공 결과를 보존합니다. 외부 사전이 단어를 찾지 못해 HTTP 404를 반환하면 RemoteRestApiReturnedError가 될 수 있지만, 이 오류 이름이 언제나 단어 없음만 뜻하는 것은 아닙니다.

오류의 의미

WebhookExecutionFailedToStart만 외부 요청이 나가지 않았다고 확정할 수 있습니다. WebhookExecutionTimedOut은 요청을 시작했지만 응답이 시간 안에 오지 않은 상태입니다. ParsingResponseFailed는 외부 요청은 성공했으나 필요한 필드 등의 해석이 실패한 상태입니다. 결과를 사용하지 않는 워크플로에서는 이 해석 실패를 최종 실패로 볼지 결정해야 합니다.

RemoteRestApiReturnedError는 REST API 소스, RemoteApiReturnedError는 그 밖의 소스에서 외부 시스템이 오류를 반환한 경우입니다. ServerError는 웹훅 서비스나 커넥터 내부, UnknownError는 어느 Foundry 서비스에 직접 귀속하지 못한 오류입니다. 새 오류 이름이 추가될 수 있으므로 기본 분기를 유지합니다.

외부 쓰기가 성공한 뒤 온톨로지 쓰기가 실패할 수 있습니다. 두 시스템이 자동으로 함께 롤백된다고 가정하지 말고 각 변경 상태를 사용자에게 확인할 수 있게 해야 합니다.

자료형과 실행 제한

지원 입출력은 Attachment, Boolean, Integer, Long, Double, String, Optional, Date, Timestamp, List, 허용 문자열 목록인 Enum과 예상 필드가 있거나 없는 Record입니다. OR 타입을 입력이나 출력에 쓰는 웹훅에는 코드가 생성되지 않습니다.

온톨로지 편집 함수 안의 요청 개수에는 별도의 개수 상한이 없지만 함수 시간 및 메모리와 웹훅 한도는 적용됩니다.

Query에서 호출하는 웹훅은 Read API여야 합니다. 쿼리는 재시도하거나 페이지 로드 때 자동 실행할 수 있으므로 외부 쓰기 API를 연결해서는 안 됩니다. 외부 변경이나 온톨로지 편집이 필요한 명시적 액션 흐름에는 OntologyEditFunction과 알맞은 액션 구성을 사용합니다.

버전과 권한

함수를 게시하면 그 시점의 최신 웹훅 버전을 함수에 고정합니다. 저장소를 다시 열어 생성하는 코드 바인딩은 최신 웹훅을 사용하므로 편집기에서 보는 버전과 과거 게시 함수가 실행할 버전이 다를 수 있습니다.

웹훅을 바꿨다면 함수를 다시 게시하고 소비 버전도 갱신해야 합니다. 이미 게시한 고정 버전은 계속 남습니다.

작업필요한 권한
함수 저장소로 웹훅 가져오기웹훅의 webhooks:editor. 기본 Editor 역할에 포함
웹훅을 호출하는 함수 게시소스의 webhooks:execute. 기본 Owner와 Editor 역할에 포함
웹훅 호출 OntologyEditFunction을 액션에 연결웹훅의 webhooks:grant-action-validated-execution과 함수 Viewer
Workshop에서 Query 웹훅 실행소스의 webhooks:execute. 기본 Owner와 Editor 역할에 포함
액션에서 OntologyEditFunction 실행액션 제출 조건 충족. 이 경로의 최종 사용자에게 소스, 웹훅과 함수 권한을 직접 검사하지 않음

액션 작성자가 제출 조건을 적절하게 구성해야 합니다. 단순히 소스를 볼 수 있다는 사실로 작업별 게시와 실행 권한을 대체할 수는 없습니다.

조사와 구성 원칙

Data Connection의 웹훅 History, Ontology Manager의 함수 사용 이력과 함수 지표, 코드 미리보기의 프로파일링 및 디버그 출력을 사용합니다.

함수에 연결하기 전에 테스트 웹훅 패널로 요청과 응답 계약을 확인하는 절차가 권장됩니다. 그 과정은 실제 외부 요청을 할 수 있습니다. 가능하면 필드가 명시된 Record를 사용하고 isOk 또는 isErr 및 error.name으로 성공과 실패를 분기합니다.