자습서: 포털 웹 API 사용
참고
2022년 10월 12일부터 Power Apps 포털이 Power Pages가 됩니다. 추가 정보: Microsoft Power Pages는 이제 일반적으로 사용할 수 있습니다(블로그)
곧 Power Apps 포털 설명서를 마이그레이션하고 Power Pages 설명서와 병합할 예정입니다.
이 자습서에서는 웹 API를 사용하여 연락처 테이블에서 레코드를 읽고, 쓰고, 업데이트하고, 삭제할 웹 페이지 및 사용자 지정 웹 템플릿을 설정합니다.
참고
이 예의 단계를 수행하는 동안 열 이름을 변경하거나 다른 테이블을 사용할 수 있습니다.
1단계 사이트 설정 만들기
포털 웹 API를 사용하기 전에 포털 관리 앱에서 필요한 사이트 설정을 활성화해야 합니다. 사이트 설정은 웹 API와 상호 작용할 때 사용하려는 테이블에 따라 다릅니다.
Power Apps(으)로 이동합니다.
왼쪽 창에서 앱을 선택합니다.
포털 관리 앱을 선택합니다.
포털 관리 앱의 왼쪽 창에서 사이트 설정을 선택합니다.
새로 만들기를 선택합니다.
이름 상자에 Webapi/contact/enabled를 입력합니다.
웹 사이트 목록에서 웹 사이트 레코드를 선택합니다.
값 상자에 true를 입력합니다.
저장하고 닫기를 선택합니다.
새로 만들기를 선택합니다.
이름 상자에 Webapi/contact/fields를 입력합니다.
웹 사이트 목록에서 웹 사이트 레코드를 선택합니다.
값 상자에
firstname,lastname,fullname,emailaddress1,telephone1을 입력합니다.저장하고 닫기를 선택합니다.
새로 만들기를 선택합니다.
이름 상자에 Webapi/error/innererror를 입력합니다.
웹 사이트 목록에서 웹 사이트 레코드를 선택합니다.
값 상자에 true를 입력합니다.
저장하고 닫기를 선택합니다.
웹 API의 사이트 설정을 확인합니다.
2단계. 권한 구성
사용자가 웹 API 기능을 사용할 수 있도록 권한을 구성해야 합니다. 이 예에서는 테이블 권한의 연락처를 활성화하고, 웹 API를 사용하여 웹 역할을 생성하고, 연락처 테이블의 테이블 권한을 이 웹 역할에 추가한 다음 사용자에게 웹 역할을 추가하여 사용자가 웹 API를 사용할 수 있도록 합니다.
포털 관리 앱의 왼쪽 창에서 테이블 권한을 선택합니다.
새로 만들기를 선택합니다.
이름 상자에서 연락처 테이블 권한을 입력합니다.
테이블 이름 목록에서 연락처(연락처) 를 선택합니다.
웹 사이트 목록에서 웹 사이트 레코드를 선택합니다.
액세스 형식 목록에서 전역을 선택합니다.
읽기, 쓰기, 만들기 및 삭제 권한을 선택합니다.
저장하고 닫기를 선택합니다.
웹 역할 만들기
웹 사이트에서 기존 웹 역할을 사용하거나 새 웹 역할을 생성할 수 있습니다.
왼쪽 창에서 웹 역할 을 선택합니다.
새로 만들기를 선택합니다.
이름 상자에 웹 API 사용자(또는 이 기능에 액세스하는 사용자의 역할을 가장 잘 반영하는 이름)를 입력합니다.
웹 사이트 목록에서 웹 사이트 레코드를 선택합니다.
저장을 선택합니다.
관련 테이블 권한 추가
신규 또는 기존 웹 역할을 사용하여 관련 > 테이블 권한을 선택합니다.
기존 테이블 권한 추가를 선택합니다.
이전에 만든 연락처 테이블 권한을 선택합니다.
추가를 선택합니다.
저장하고 닫기를 선택합니다.
웹 역할에 연락처 추가
왼쪽 창에서 연락처를 선택합니다.
웹 API 예제에서 사용할 연락처를 선택합니다.
참고
이 연락처는 웹 API를 테스트하기 위해 이 예제에서 사용되는 사용자 계정입니다. 포털에서 올바른 연락처를 선택해야 합니다.
관련 항목 > 웹 역할을 선택합니다.
기존 웹 역할 추가를 선택합니다.
앞에서 만든 웹 API 사용자 역할을 선택합니다.
추가를 선택합니다.
저장하고 닫기를 선택합니다.
3단계. 웹 페이지 만들기
이제 웹 API를 활성화하고 사용자 권한을 구성했으므로 레코드를 보고 편집하고 만들고 삭제할 수 있는 샘플 코드가 포함된 웹 페이지를 만듭니다.
포털 관리 앱의 왼쪽 창에서 웹 페이지를 선택합니다.
새로 만들기를 선택합니다.
이름 상자에 webapi를 입력합니다.
웹 사이트 목록에서 웹 사이트 레코드를 선택합니다.
상위 페이지에 대해 홈을 선택합니다.
부분 URL에 webapi를 입력합니다.
페이지 템플릿에 대해 홈을 선택합니다.
게시 상태에 대해 게시됨을 선택합니다.
저장을 선택합니다.
관련 항목 > 웹 페이지를 선택합니다.
웹 페이지 관련 보기에서 webapi를 선택합니다.
콘텐츠 섹션으로 아래로 스크롤한 다음, 복사(HTML)(HTML 디자이너)로 이동합니다.
HTML 탭을 선택합니다.
다음 샘플 코드 조각을 복사하여 HTML 디자이너에 붙여넣습니다.
<!-- Sample code for Web API demonstration --> <style> #processingMsg { width: 150px; text-align: center; padding: 6px 10px; z-index: 9999; top: 0; left: 40%; position: fixed; -webkit-border-radius: 0 0 2px 2px; border-radius: 0 0 2px 2px; -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); display: none; } table td[data-attribute] .glyphicon-pencil { margin-left: 5px; opacity: 0; } table td[data-attribute]:hover .glyphicon-pencil { opacity: 0.7; } </style> <script> $(function() { //Web API ajax wrapper (function(webapi, $) { function safeAjax(ajaxOptions) { var deferredAjax = $.Deferred(); shell.getTokenDeferred().done(function(token) { // Add headers for ajax if (!ajaxOptions.headers) { $.extend(ajaxOptions, { headers: { "__RequestVerificationToken": token } }); } else { ajaxOptions.headers["__RequestVerificationToken"] = token; } $.ajax(ajaxOptions) .done(function(data, textStatus, jqXHR) { validateLoginSession(data, textStatus, jqXHR, deferredAjax.resolve); }).fail(deferredAjax.reject); //ajax }).fail(function() { deferredAjax.rejectWith(this, arguments); // On token failure pass the token ajax and args }); return deferredAjax.promise(); } webapi.safeAjax = safeAjax; })(window.webapi = window.webapi || {}, jQuery) // Notification component var notificationMsg = (function() { var $processingMsgEl = $('#processingMsg'), _msg = 'Processing...', _stack = 0, _endTimeout; return { show: function(msg) { $processingMsgEl.text(msg || _msg); if (_stack === 0) { clearTimeout(_endTimeout); $processingMsgEl.show(); } _stack++; }, hide: function() { _stack--; if (_stack <= 0) { _stack = 0; clearTimeout(_endTimeout); _endTimeout = setTimeout(function() { $processingMsgEl.hide(); }, 500); } } } })(); // Inline editable table component var webAPIExampleTable = (function() { var trTpl = '<% _.forEach(data, function(data){ %>' + '<tr data-id="<%=data.id%>" data-name="<%=data.fullname%>">' + '<% _.forEach(columns, function(col){ %>' + '<td data-attribute="<%=col.name%>" data-label="<%=col.label%>" data-value="<%=data[col.name]%>">' + '<%-data[col.name]%><i class="glyphicon glyphicon-pencil"></i>' + '</td>' + '<% }) %>' + '<td>' + '<button class="btn btn-default delete" type="submit"><i class="glyphicon glyphicon-trash" aria-hidden="true"></i></button>' + '</td>' + '</tr>' + '<% }) %>'; var tableTpl = '<table class="table table-hover">' + '<thead>' + '<tr>' + '<% _.forEach(columns, function(col){ %>' + '<th><%=col.label%></th>' + '<% }) %>' + '<th>' + '<button class="btn btn-default add" type="submit">' + '<i class="glyphicon glyphicon-plus" aria-hidden="true"></i> Add Sample Record' + '</button>' + '</th>' + '</tr>' + '</thead>' + '<tbody>' + trTpl + '</tbody>' + '</table>'; function getDataObject(rowEl) { var $rowEl = $(rowEl), attrObj = { id: $rowEl.attr('data-id'), name: $rowEl.attr('data-name') }; $rowEl.find('td').each(function(i, el) { var $el = $(el), key = $el.attr('data-attribute'); if (key) { attrObj[key] = $el.attr('data-value'); } }) return attrObj; } function bindRowEvents(tr, config) { var $row = $(tr), $deleteButton = $row.find('button.delete'), dataObj = getDataObject($row); $.each(config.columns, function(i, col) { var $el = $row.find('td[data-attribute="' + col.name + '"]'); $el.on('click', $.proxy(col.handler, $el, col, dataObj)); }); //User can delete record using this button $deleteButton.on('click', $.proxy(config.deleteHandler, $row, dataObj)); } function bindTableEvents($table, config) { $table.find('tbody tr').each(function(i, tr) { bindRowEvents(tr, config); }); $table.find('thead button.add').on('click', $.proxy(config.addHandler, $table)); } return function(config) { var me = this, columns = config.columns, addHandler = config.addHandler, deleteHandler = config.deleteHandler, $table; me.render = function(el) { $table = $(el).html(_.template(tableTpl)({ columns: columns, data: me.data })).find('table'); bindTableEvents($table, { columns: columns, addHandler: addHandler, deleteHandler: deleteHandler }); } me.addRecord = function(record) { $table.find('tbody tr:first').before(_.template(trTpl)({ columns: columns, data: [record] })); bindRowEvents($table.find('tbody tr:first'), config); } me.updateRecord = function(attributeName, newValue, record) { $table.find('tr[data-id="' + record.id + '"] td[data-attribute="' + attributeName + '"]').text(newValue); } me.removeRecord = function(record) { $table.find('tr[data-id="' + record.id + '"]').fadeTo("slow", 0.7, function() { $(this).remove(); }); } }; })(); //Applicaton ajax wrapper function appAjax(processingMsg, ajaxOptions) { notificationMsg.show(processingMsg); return webapi.safeAjax(ajaxOptions) .fail(function(response) { if (response.responseJSON) { alert("Error: " + response.responseJSON.error.message) } else { alert("Error: Web API is not available... ") } }).always(notificationMsg.hide); } function loadRecords() { return appAjax('Loading...', { type: "GET", url: "/_api/contacts?$select=fullname,firstname,lastname,emailaddress1,telephone1", contentType: "application/json" }); } function addSampleRecord() { //Sample data to create a record - change as appropriate var recordObj = { firstname: "Willie", lastname: "Huff" + _.random(100, 999), emailaddress1: "Willie.Huff@contoso.com", telephone1: "555-123-4567" }; appAjax('Adding...', { type: "POST", url: "/_api/contacts", contentType: "application/json", data: JSON.stringify(recordObj), success: function(res, status, xhr) { recordObj.id = xhr.getResponseHeader("entityid"); recordObj.fullname = recordObj.firstname + " " + recordObj.lastname; table.addRecord(recordObj); } }); return false; } function deleteRecord(recordObj) { var response = confirm("Are you sure, you want to delete \"" + recordObj.name + "\" ?"); if (response == true) { appAjax('Deleting...', { type: "DELETE", url: "/_api/contacts(" + recordObj.id + ")", contentType: "application/json", success: function(res) { table.removeRecord(recordObj); } }); } return false; } function updateRecordAttribute(col, recordObj) { var attributeName = col.name, value = recordObj[attributeName], newValue = prompt("Please enter \"" + col.label + "\"", value); if (newValue != null && newValue !== value) { appAjax('Updating...', { type: "PUT", url: "/_api/contacts(" + recordObj.id + ")/" + attributeName, contentType: "application/json", data: JSON.stringify({ "value": newValue }), success: function(res) { table.updateRecord(attributeName, newValue, recordObj); } }); } return false; } var table = new webAPIExampleTable({ columns: [{ name: 'firstname', label: 'First Name', handler: updateRecordAttribute }, { name: 'lastname', label: 'Last Name', handler: updateRecordAttribute }, { name: 'emailaddress1', label: 'Email', handler: updateRecordAttribute }, { name: 'telephone1', label: 'Telephone', handler: updateRecordAttribute }], data: [], addHandler: addSampleRecord, deleteHandler: deleteRecord }); loadRecords().done(function(data) { table.data = _.map(data.value, function(record){ record.id = record.contactid; return record; }); table.render($('#dataTable')); }); }); </script> <div id="processingMsg" class="alert alert-warning" role="alert"></div> <div id="dataTable"></div>
저장 및 닫기를 선택합니다.
4단계. 포털 캐시 지우기
웹 API 기능을 테스트하기 위해 webapi 샘플 페이지를 작성했습니다. 시작하기 전에 포털 관리 앱의 변경 내용이 포털에 반영되도록 Power Apps 포털 캐시가 지워졌는지 확인합니다.
중요: 포털 서버 측 캐시를 지우면 Microsoft Dataverse에서 데이터를 다시 로드하는 동안에 포털 성능이 일시적으로 저하될 수 있습니다.
캐시를 지우려면
관리자 웹 역할의 구성원으로 포털에 로그인합니다.
끝에 /_‑/_services/about 을 추가하여 URL을 변경합니다. 예를 들어 포털 URL이 https://contoso.powerappsportals.com인 경우 https://contoso.powerappsportals.com/_services/about으로 변경합니다.
참고: 캐시를 지우려면 관리자 웹 역할의 구성원이어야 합니다. 빈 화면이 표시되는 경우 웹 역할 할당을 확인합니다.
캐시 지우기를 선택합니다.
추가 정보: 포털에 대한 서버측 캐시 지우기
5단계 웹 API를 사용하여 읽기, 보기, 편집, 생성 및 삭제
이전에 생성한 URL webapi가 포함된 샘플 웹페이지를 이제 테스트할 준비가 되었습니다.
웹 API 기능을 테스트하려면 다음을 수행하십시오.
앞에서 만든 웹 API 사용자 역할이 할당된 사용자 계정으로 포털에 로그인합니다.
앞에서 만든 webapi 웹 페이지로 이동합니다. *https://contoso.powerappsportals.com/webapi*을 예로 들 수 있습니다. 웹 API는 Microsoft Dataverse에서 레코드를 검색합니다.
샘플 레코드 추가를 선택하고 스크립트에서 샘플 레코드를 추가합니다.
필드를 선택합니다. 이 예에서는 이메일을 선택하여 연락처의 이메일 주소를 변경합니다.
을 선택하여 레코드를 삭제합니다.
레코드를 읽고, 편집하고, 만들고, 삭제할 수 있는 샘플이 포함된 웹 페이지를 만들었으므로 이제 양식과 레이아웃을 사용자 지정할 수 있습니다.
다음 단계
참고 항목:
포털 웹 API 개요
포털은 웹 API를 사용하여 작업을 쓰고 업데이트하고 삭제합니다
포털은 웹 API를 사용하여 작업을 읽습니다
열 권한 구성
참고
귀사의 설명서 언어 기본 설정에 대해 말씀해 주시겠습니까? 간단한 설문 조사에 응해주세요. (이 설문 조사는 영어로 되어 있습니다.)
이 설문 조사는 약 7분 정도 걸립니다. 개인 데이터는 수집되지 않습니다(개인정보처리방침).