스크립팅된 REST API 예제 - 스트리밍 및 객체 직렬화 비교

  • 릴리스 버전: Zurich
  • 업데이트 날짜 2025년 07월 31일
  • 소요 시간: 10분
  • 다음 예제에서는 스트리밍을 사용하고 기본 개체 serialization을 사용하여 JSON 응답을 보내는 방법을 보여 줍니다.

    스트리밍 대 객체 직렬화

    응답을 보낼 때 응답을 스트림으로 보내거나 개체를 serialize할 수 있습니다. 두 접근 방식 모두 장점과 단점이 있습니다. 통합의 필요에 따라 기술을 선택합니다.

    일반적으로 응답 개체가 단순하고 XML 또는 JSON으로 표현될 수 있으며 일관된 크기인 경우 개체 serialization을 사용합니다. XML 또는 JSON 이외의 형식을 사용하거나 응답 크기가 다른 경우 스트리밍을 사용합니다.

    응답 스트리밍

    스트리밍 응답을 사용하면 응답시간, 인스턴스 성능 및 콘텐츠 유연성에 이점이 있지만 스크립트의 복잡성이 추가됩니다. 스트리밍을 사용하는 경우 응답의 형식을 지정하고, 응답 상태를 설정하고, Content-Type 헤더를 설정해야 합니다. 응답을 스트리밍할 때 스트리밍을 시작하기 전에 전체 응답을 생성할 필요가 없기 때문에 요청 사용자는 신속하게 응답을 받습니다.

    이 예시에서는 스트리밍을 사용하여 인시던트 기록의 배열을 반환하는 스크립팅된 REST 자원 스크립트를 보여줍니다.

    /**
     *  Sample Scripted REST Resource that returns custom JSON objects with properties from Incident GlideRecords
     *  This sample uses ServiceNow JavaScript API to query incident records
     *  and then iterates over those records to build and stream a custom JSON object that 
     *  includes some values from the incidents
     */
    (function runOperation(/*RESTServiceRequest*/ request, /*RESTServiceResult*/ response) {
        var writer = response.getStreamWriter(),
            hdrs = {},
            table = 'incident',
            record_limit = 100,
            gr = new GlideRecord(table);
    
    
        hdrs['Content-Type'] = 'application/json';
        response.setStatus(200);
        response.setHeaders(hdrs);
    
        gr.setLimit(record_limit);
        gr.query();
    
        //  start building response object
        writer.writeString("{\"results\":[");
    
    
        //  iterate over incident records and build JSON representations to be streamed out.
        while (gr.next()) {
            var incidentObj = {};
    
            incidentObj.number = gr.number + '';
            incidentObj.short_description = gr.short_description + '';
            writer.writeString(global.JSON.stringify(incidentObj));
    
            if (gr.hasNext()) {
                writer.writeString(",");
            }
        }
    
        //  close the response object
        writer.writeString("]}");
    })(request, response);
    

    이 자원에 대한 요청은 다음 응답을 반환합니다.

    
    //  sample response
    /*
     HTTP/1.1 200 OK
     Content-Type: application/json
     Server: ServiceNow
    
      // sample response number of records returned has been truncated for this example
    
     {
     "results": [
     {
     "number": "INC0011301",
     "short_description": "lorem ipsum short description 0 my new incident"
     },
     {
     "number": "INC0011302",
     "short_description": "lorem ipsum short description 1 my new incident"
     },
     {
     "number": "INC0011303",
     "short_description": "lorem ipsum short description 2 my new incident"
     },
     {
     "number": "INC0011304",
     "short_description": "lorem ipsum short description 3 my new incident"
     },
     {
     "number": "INC0011309",
     "short_description": "lorem ipsum short description 8 my new incident"
     },
     {
     "number": "INC0011310",
     "short_description": "lorem ipsum short description 9 my new incident"
     },
     {
     "number": "INC0011311",
     "short_description": "lorem ipsum short description 0 my new incident"
     },
     {
     "number": "INC0011312",
     "short_description": "lorem ipsum short description 1 my new incident"
     },
     {
     "number": "INC0011313",
     "short_description": "lorem ipsum short description 2 my new incident"
     },
     {
     "number": "INC0011314",
     "short_description": "lorem ipsum short description 3 my new incident"
     },
     {
     "number": "INC0011315",
     "short_description": "lorem ipsum short description 4 my new incident"
     },
     {
     "number": "INC0011326",
     "short_description": "lorem ipsum short description 15 my new incident"
     }
     ]
     }
     */
    

    스트리밍 페이지 매김

    쿼리당 제한된 수의 레코드만 보내도록 큰 테이블의 페이지를 매기려면 이 범위가 지정된 GlideRecord - chooseWindow(Number, firstRow, Number, lastRow, boolean, forceCount) 방법을 사용합니다. 커뮤니티 문서 페이지 매김된 Glide 기록 + 확장된 GR 메서드 지원은chooseWindow() 를 사용하여 페이지 매김을 달성하는 방법을 보여 주며, 페이지 매김을 고유한 사용 사례에 맞게 조정할 수 있습니다.

    객체 만들기

    객체 직렬화를 사용하면 ServiceNow에서 제공하는 직렬화 및 콘텐츠 협상을 이용할 수 있습니다. 스트리밍 대신 개체를 serialize하는 경우 클라이언트가 응답을 받기 전에 전체 개체를 만들고 serialize해야 합니다. 이로 인해 응답이 지연되거나 응답 객체가 매우 큰 경우 많은 양의 시스템 자원이 필요할 수 있습니다. 객체 직렬화는 XML 또는 JSON 응답에만 사용할 수 있습니다. 다른 형식을 사용하는 응답은 스트리밍을 사용해야 합니다.

    이 예에서는 스트리밍 예와 동일한 인시던트 데이터를 반환하지만 응답을 보내기 전에 배열의 모든 응답 데이터를 수집합니다.

    /**
     *  Sample Scripted REST Resource returns an array of custom JSON objects that include 2 incident properties.
     *  This sample uses ServiceNow JavaScript API to query incident records and then iterates
     *  over those records building a custom JSON object that includes 2 values from the incident records.
     *  note that because we are returning a simple JSON object we can rely on built in serialization
     *  to set the content-type header as well as response status. The 'result_arr' object will not be returned
     *  until it has been completely built and stored
     */
    (function runOperation(/*RESTServiceRequest*/ request, /*RESTServiceResult*/ response) {
        var table = 'incident',
            record_limit = 100,
            result_arr = [],
            gr = new GlideRecord(table);
    
    
        gr.setLimit(record_limit);
        gr.query();
    
    
        //  iterate over incident records and build JSON representations to be streamed out.
        while (gr.next()) {
            var incidentObj = {};
    
            incidentObj.number = gr.number + '';
            incidentObj.short_description = gr.short_description + '';
    
            result_arr.push(incidentObj);
        }
    
        return result_arr;
    })(request, response);
    

    이 자원에 대한 요청은 다음 응답을 반환합니다.

    
    /*
     HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Server: ServiceNow
    
     // sample response number of records returned has been truncated for this example
    
     {
     "result": [{
     "short_description": "lorem ipsum short description 0 my new incident",
     "number": "INC0011301"
     }, {
     "short_description": "lorem ipsum short description 1 my new incident",
     "number": "INC0011302"
     }, {
     "short_description": "lorem ipsum short description 2 my new incident",
     "number": "INC0011303"
     }, {
     "short_description": "lorem ipsum short description 3 my new incident",
     "number": "INC0011304"
     }, {
     "short_description": "lorem ipsum short description 4 my new incident",
     "number": "INC0011305"
     }, {
     "short_description": "lorem ipsum short description 5 my new incident",
     "number": "INC0011306"
     }, {
     "short_description": "lorem ipsum short description 6 my new incident",
     "number": "INC0011307"
     }, {
     "short_description": "lorem ipsum short description 7 my new incident",
     "number": "INC0011308"
     }, {
     "short_description": "lorem ipsum short description 8 my new incident",
     "number": "INC0011309"
     }, {
     "short_description": "lorem ipsum short description 9 my new incident",
     "number": "INC0011310"
     }]
     }
     */