Advanced Guides
Parse 서버 3.1로 전환하여 앱 성능 최적화하기
23 분
parse server 3 1로 앱의 성능을 높이세요 소개 parse 커뮤니티는 최근 parse server 3 1 버전 https //docs parseplatform org/parse server/guide/ 을 출시했습니다 이 업데이트는 cloud code 구문을 정리하여 es6 async 및 await 구조를 활용하기에 훨씬 더 용이하게 만들었습니다 또한 parse 사용과 관련된 몇 가지 특이점이 제거되었습니다 예를 들어, cloud 함수는 response 객체에서 error error 또는 success success 메시지를 사용하는 대신 단순히 promise를 반환합니다 대시보드에서 back4app의 앱을 쉽게 업그레이드할 수 있습니다 이 가이드는 3 1의 새로운 기능을 활용하기 위해 코드를 업그레이드하는 방법을 보여줍니다 이 가이드를 따르려면 제공된 예제 프로젝트 를 확인해 보시기 바랍니다 이 튜토리얼은 john considine https //github com/considine , k optional https //koptional com/ 의 수석 개발자가 작성한 게스트 튜토리얼입니다 목표 back4app parse server를 3 1로 업데이트하고 cloud code를 그에 맞게 마이그레이션합니다 전제 조건 이 튜토리얼을 완료하려면 다음이 필요합니다 ° parse server 2 x를 사용하는 기존 back4app 애플리케이션 ° back4app에서 앱을 만드는 방법을 배우려면 새 앱 만들기 튜토리얼 을 따르세요 변경 사항 요약 가장 주목할 만한 변경 사항은 다음과 같습니다 1\ 클라우드 코드가 parse sdk 2 x로 실행됩니다 이전에는 클라우드 코드가 parse sdk 1 x로 실행되었습니다 parse server 3 1부터는 parse sdk 2 x로 실행됩니다 자세한 내용을 이해하려면 parse sdk 릴리스 를 확인하세요 이 주요 버전 업그레이드는 주로 버그 수정과 관련이 있습니다 또한 containedby 및 includeall 쿼리 메서드와 포함된 객체를 가져오는 기능이 추가되었습니다 2 집계 업데이트 parse 2 7 1부터는 쿼리에서 aggregate 메서드를 사용할 수 있습니다 이를 통해 기본 데이터베이스를 좀 더 활용할 수 있습니다 이제 aggregate 메서드 의 구문이 parse query parse query 에서 업데이트되었습니다 쿼리를 두 단계로 실행할 수 있습니다 match match 단계와 group group 단계입니다 이전에는 파이프라인 객체에 pipeline 키가 필요하지 않았습니다 기본 api로 인해 이제는 pipeline 키를 명시적으로 포함해야 합니다 값은 하나 또는 두 개의 단계로 구성된 배열이어야 하며, group group 및 match match 이 포함되어야 합니다 자세한 예시는 parse 공식 문서 를 참조하세요 3 내부 최적화 일부 내부 최적화가 이루어졌습니다 예를 들어, parse livequery 는 데이터와 함께 클래스 수준 권한(clps)을 가져와서 데이터베이스 접근을 두 번 하지 않도록 합니다 4\ parse 재설정 이메일 비밀번호 재설정 이메일을 요청할 때, 서버는 해당 이메일이 저장되지 않았더라도 성공을 반환합니다 또한, 사용자의 이메일이 재설정될 때 비밀번호 재설정 토큰은 만료됩니다 5\ 클라우드 트리거 업데이트 이번 릴리스에서는 beforesave 및 aftersave 트리거를 동일한 객체에서 공유할 수 있습니다 예를 들어 1 parse cloud beforesave('comment', async request => { 2 request context = { 3 foo 'bar' 4 }; 5 }); 6 7 parse cloud aftersave('comment', async request => { 8 console log(request context foo); //bar 9 }); parse server의 변경 사항에 대한 자세한 내용은 공식 parse 3 1 변경 로그를 클릭하여 확인할 수 있습니다 여기 6\ 라이브 쿼리 개선 parse livequery 클라이언트를 사용하면 쿼리에 구독하고 서버에서 업데이트를 받을 수 있습니다 전통적인 쿼리는 클라이언트에 의해 한 번만 실행되므로 메시징과 같은 경우에 매우 유용합니다 back4app을 사용하면 이 기술을 활용할 수 있습니다 https //www back4app com/docs/platform/parse server live query example 3 x 버전의 출시와 함께, parse 커뮤니티는 livequery를 위한 시스템을 개선했습니다 acls https //docs parseplatform org/js/guide/#security for other objects 이제 라이브 쿼리의 subscribe 메서드에 세션 토큰을 전달할 수 있으며, parse 서버는 이 사용자가 접근할 수 있는 결과만 반환하도록 관리합니다 예를 들어, 사용자는 특정 '메시지'에 대해 읽기/쓰기 접근 권한이 있을 수 있지만, 모든 메시지에 대해 그렇지는 않을 수 있습니다 1 let query = new parse query('message'); 2 // you can get session token with 3 // parse user current() getsessiontoken() when logged in 4 let subscription = client subscribe(query, sessiontoken); 위 코드는 사용자가 접근할 수 있는 모든 메시지에 자동으로 구독하게 하여, 특정 메시지를 쿼리하는 책임에서 벗어나게 해줍니다 변경 사항의 주요 부분은 cloud code가 처리되는 방식과 관련이 있습니다 이를 위해 아래의 마이그레이션 가이드를 참조하십시오 1 기술 기초 정렬하기 우리는 2 x 릴리스를 사용하는 예제 클라우드 프로젝트로 시작할 것입니다 그렇게 하면 적절한 구문 변경을 탐색할 수 있습니다 저장소 를 이 예제 프로젝트에 사용할 수 있습니다 비동기 및 대기(async/await)에 익숙하다면 이 섹션을 건너뛸 수 있습니다 자바스크립트에서 비동기 코드의 진화는 다음과 같습니다 콜백 함수 프라미스 비동기 / 대기 모든 현대 자바스크립트 애플리케이션은 아마도 이 세 가지를 모두 사용할 것입니다 콜백 함수는 다른 함수에 인수로 함수를 전달하는 것을 포함합니다 이 두 번째 함수는 어떤 시점에서 첫 번째 함수를 실행할 수 있습니다 1 // callbacks 2 // executes callback function after waiting 100 milliseconds 3 settimeout(function() { 4 alert('my callback function'); 5 }, 100); 콜백은 필수적이지만 많은 콜백을 연결할 때는 다루기 어려울 수 있습니다 특히 여러 겹으로 중첩하는 것은 읽기 어려울 수 있으며, 오류 처리가 어려워집니다 따라서 es2015에서 promise가 도입되었습니다 1 // promises 2 // executes several promises in a row with no significant nesting 3 const mypromise = new promise(function(resolve, reject) { 4 settimeout(function() { 5 if (math random() < 0 2) reject(new error('random failure!')); 6 resolve('finished'); 7 }, 100); 8 }); 9 10 // executes this promise 4 times and catches errors involved 11 mypromise 12 then(() => mypromise) 13 then(() => mypromise) 14 then(() => mypromise) 15 then(() => mypromise) 16 catch(e => console log(e)); 프로미스는 비동기 프로그래밍의 가독성을 향상시킵니다 또한 파이프라인을 더 명확하게 만듭니다 그러나 es2017 에서는 async / await 구조로 더 큰 발전이 있었습니다 이제 코드는 then / catch 블록에 의존하지 않고 프로미스의 결과를 기다릴 수 있습니다(이 또한 읽기 어려워질 수 있습니다) 1 // using the definition of mypromise from the above code 2 async function foo() { 3 try { 4 let result = await mypromise; 5 result = await mypromise; 6 result = await mypromise; 7 } catch (e) { 8 console log(e); 9 } 10 } 아마도 아주 간단한 예시로는, 이것이 일반 프로미스보다 더 우아해 보이지 않을 수 있습니다 그러나 비동기 함수의 결과를 기다리는 것은 우리가 하고자 하는 일입니다 따라서 이는 코드의 가독성을 진정으로 최적화합니다 비동기/대기 지원 앞서 언급한 바와 같이, async/await는 ecmascript 2017 사양 (es8)에 포함되었습니다 서버 코드의 경우, 버전 관리는 거의 문제가 되지 않으며, 이 기능을 지원하는 node js 버전으로 업데이트할 수 있습니다 안심하세요, back4app의 환경은 최근 안정적인 버전을 지원합니다 브라우저 코드의 경우, babel 과 같은 트랜스파일러는 async / await를 사용하는 코드와 호환되는 es2016 코드를 생성하며, 현대 브라우저에서 작동합니다 2 코드를 다르게 생각하기 cloud code의 주요 변화는 개발자가 하는 일과 라이브러리가 하는 일의 차이입니다 이전에는 응답을 명시적으로 관리해야 했습니다 대부분의 cloud code는 비동기적으로 실행되므로 데이터베이스 쿼리 및 쓰기를 수행하므로 약간의 보일러플레이트 코드를 줄이기 위해 promise를 반환하는 것이 더 합리적입니다 cloud 함수의 직관은 서버 측 코드를 작성할 때 최소한의 설정 및 구성이 필요하다는 것입니다 이 릴리스는 그 아이디어를 구현하고 있습니다; 리팩토링하고 새로운 함수를 만들 때 이 점을 염두에 두세요 parse server 3 1에서 cloud code 함수가 어떻게 작동하는지 보여주기 위해, 우리는 마이그레이션 이전의 parse server 버전에서 기능적 cloud code 샘플을 다시 작성했습니다 이 코드는 여기 에서 찾을 수 있습니다 동일한 cloud code 함수는 아래와 같이 parse 3 1에서 작성되었습니다 1 // cloud code before migration 2 // full code found in link above 3 const post = 'post'; 4 parse cloud define('posts\ get', function(request, response) { 5 // needs a post id 6 return new parse query(post) 7 get(request params id, { usemasterkey true }) 8 then(post => { 9 response success(post); 10 }) 11 catch(e => { 12 response error({ message e message }); 13 }); 14 }); 3 모든 비동기 마커 추가하기 await를 사용하는 모든 함수는 async 수정자로 선언해야 합니다 이 간단한 리팩토링은 모든 cloud functions에 async를 추가합니다 또한 이 경우 더 간결한 화살표 함수 로 교체할 것입니다 (그리고 업데이트된 공식 parse 가이드에서 사용하는 것입니다) 1 // snippet of step 2 code refactoring see full code 2 // here in the link at the top of this step 3 const post = 'post'; 4 const comment = 'comment'; 5 6 parse cloud define('posts\ get', async (request) => { 7 // needs a post id 8 return new parse query(post) 9 get(request params id, { usemasterkey true }); 10 } 리팩토링 후 귀하의 코드는 이것 처럼 보일 것입니다 지금까지는 별로 이상한 것이 없습니다 다음 단계에서는 이 변경에 대한 가치를 얻을 것입니다 4 응답에 대한 참조 제거, await 사용 당신의 코드는 이것처럼 이 리팩토링 후에 보일 것입니다 이 단계는 조금 더 까다롭습니다 우리는 다음을 해야 합니다 ‘response’ 변수를 모두 제거하고 대신 프로미스를 반환합니다 여러 쿼리/저장 함수의 경우, 응답을 기다립니다 이것이 어떻게 이루어지는지 확인하려면 댓글 생성 메서드를 확인하세요 1 // snippet of step 3 code refactoring see full code 2 // here in the link at the top of this step 3 parse cloud define('comment\ create', async request => { 4 // post should have text and should have a user and a post id 5 if (!request user) { 6 throw new error('unauthenticated!'); 7 } 8 9 if (!request params text) { 10 throw new error('a comment needs text!'); 11 } 12 if (!request params post id) { 13 throw new error('a comment needs a post!'); 14 } 15 16 // get the post 17 18 const post = await new parse query(post) get(request params post id, { 19 usemasterkey true 20 }); 21 return new parse object(comment, { 22 text request params text, 23 user request user, 24 post post 25 }) save(null, { usemasterkey true }); 26 }); 다음 사항에 유의하세요 이제 javascript 오류가 발생하며 response error를 호출하지 않습니다 parse는 이를 응답으로 변환하는 작업을 처리합니다 ‘게시물’ 또는 ‘댓글’을 삭제하려면 먼저 객체를 가져온 다음 삭제해야 합니다 ‘await’를 사용하면 삭제 메서드가 블록 외부에서 저장된 객체에 접근할 수 있습니다 이것으로 마이그레이션을 위한 모든 필요한 리팩토링이 완료되었습니다 즉, 이 단계까지 진행했다면 축하합니다! 귀하의 코드는 back4app parse 3 1에서 실행될 것입니다! 5 고급 트릭 (선택 사항) 다음 변경 사항은 선택 사항이지만 코드를 상당히 줄일 수 있습니다 저는 이들이 보일러플레이트를 줄여준다고 생각합니다 아마도 매개변수나 인증된 사용자에 대한 많은 수동 검사를 보셨을 것입니다 이러한 검사는 이상한 동작이 발생하지 않도록 보장합니다 예를 들어, 우리는 'post' 객체에 텍스트가 필요하다고 결정했으므로 'text' 매개변수가 전달되지 않으면 객체는 텍스트 없이 저장됩니다 이를 방지하는 한 가지 방법은 텍스트가 전달되었는지 확인하는 것입니다 하지만 수동 검사는 시간이 많이 걸리고 우아하지 않을 수 있습니다 이 섹션에서는 객체 구조 분해 를 활용하여 이러한 검사를 암묵적으로 완료합니다 구조 분해가 무엇인지 모른다면 위의 문서를 참조해야 합니다 하지만 간단히 말하면, 이는 객체의 속성을 매우 간결한 구문으로 변수로 변환할 수 있게 해줍니다 1 // this 2 var obj = { 3 hi true, 4 bye false 5 }; 6 var hi = obj hi; 7 var bye = obj bye; 8 9 // is equivalent to this 10 var obj = { 11 hi true, 12 bye false 13 }; 14 var { hi, bye } = obj; 15 16 console log(hi); 17 // true 18 console log(bye); 19 // false 구조 분해 할당은 수동 할당보다 덜 장황합니다 또한 매개변수 변수를 즉석에서 선언할 수 있어 좋습니다 1 parse cloud define('posts\ get', async ({ params { id } }) => { 2 // id is declared 3 }); es2015 표기법과 결합하면 객체 초기화 를 통해 매개변수 검사를 최적화할 수 있습니다 이렇게 할 수 있습니다 1 // iterates through object's keys makes sure, for each key, the value is set 2 const assertparams = parameter obj => { 3 for (var key of object keys(parameter obj)) { 4 if (typeof parameter obj\[key] === 'undefined') 5 throw new error(`missing parameter ${key}`); 6 } 7 }; 8 9 var obj = { 10 hi true, 11 bye false 12 }; 13 var { hi, undef, bye } = obj; // undef will be undefined 14 var check 1 = { hi, bye }; 15 var check 2 = { hi, undef }; 16 17 // check = { hi true, no undefined } 18 assertparams(check 1); // passes 19 assertparams(check 2); // throws error 그래서 우리의 parse 코드는 이렇게 할 수 있습니다 1 // snippet of advanced code refactoring see full code 2 // here in the link at the top of this step 3 parse cloud define('posts\ delete', async ({ user, params { id } }) => { 4 // makes sure user is authenticated, and id parameter is passed 5 assertparams({ user, id }); 6 const post = await new parse query(post) get(id, { 7 usemasterkey true 8 }); 9 return post destroy({ usemasterkey true }); 10 }); 이것이 벅차게 느껴진다면 걱정하지 마세요 전체 코드 예제가 도움이 될 수 있습니다 간단히 말해, ‘assertparams’는 값이 정의되지 않은 경우 오류를 발생시키는 유틸리티 함수입니다 객체 구조 분해와 es2015 객체 초기화를 결합하여 한 번에 매개변수를 확인할 수 있습니다 이것은 시간이 지나면서 보기 흉해지기 시작하는 8개 또는 9개의 수동 검사를 제거합니다 6 back4app에서 업그레이드하기 코드를 마이그레이션한 후, back4app에서 실행되도록 하기 위해 두 가지를 더 해야 합니다 back4app 서버 버전을 업그레이드하세요 새로운 클라우드 코드를 업로드하세요 첫 번째 단계에 대해 간단히 언급한 적이 있습니다 back4app에 로그인하고 앱의 대시보드로 이동하기만 하면 됩니다 거기서 왼쪽의 “서버 설정”을 선택한 다음 “parse 서버 관리” 카드의 “설정” 버튼을 클릭하세요 그런 다음 parse server 3 1 1 라디오 버튼을 선택하고 “저장”을 클릭하면 됩니다 마지막으로, back4app cli https //blog back4app com/2017/01/20/cli parse server/ 를 통해 또는 대시보드를 사용하여 수동으로 코드를 업로드할 수 있습니다 이 단계에 대한 추가 정보가 필요하면 이 가이드 https //www back4app com/docs/android/parse cloud code 를 참조하세요 새 버전 출시 관련 메모 코드가 복잡하다면 이 두 단계를 수행하기 전에 테스트를 실행하는 것이 좋습니다 back4app에는 이를 수행하는 방법에 대한 가이드가 있습니다 여기 와 여기 마지막으로, 이러한 변화가 중요한 점을 주목하는 것이 중요합니다 우리가 2 x parse server에서 작성한 코드는 실패할 것이고, 2 x 코드를 3 1 서버에서 사용하면 또한 실패할 것입니다 따라서 업그레이드된 cloud code를 업로드할 때 back4app parse 버전을 반드시 업그레이드해야 합니다 많은 사용자가 있고 코드 업로드와 버전 업그레이드가 약간 비동기화되는 것에 대해 걱정된다면, 다음과 같은 방법을 사용할 수 있습니다 1 const serverversion = 2 parse coremanager get('version') === 'js1 11 1' ? 'old' 'new'; 3 4 if (serverversion === 'new') { 5 parse cloud define('posts\ get', async ({ params { id } }) => { 6 assertparams({ id }); 7 // needs a post id 8 return new parse query(post) get(id, { 9 usemasterkey true 10 }); 11 }); 12 } else if (serverversion === 'old') { 13 // old definition here 14 } 이 코드는 동적으로 버전을 파악하고 그에 따라 cloud functions를 정의합니다 이를 업로드한 후 3 1로 변경하고, 이전 부분을 제거한 코드를 다시 업로드할 수 있습니다 처음에 체크를 포함하는 것은 코드가 충돌하는 지점이 없도록 보장합니다 몇 초 안에 업그레이드하고 업로드할 수 있으므로 일반적으로 필요하지 않습니다 결론 이 가이드에서는 cloud code를 parse 3 1 릴리스로 마이그레이션하는 방법을 간단히 설명했습니다 이러한 변경을 한 후 back4app 버전을 3 1로 올리는 것을 잊지 마세요 또한 중요하게도, 이 가이드는 parse 3 1이 활용하는 개선된 구문을 보여주었습니다 우리의 리팩토링은 코드베이스를 약 160줄에서 약 90줄로 줄였고, 훨씬 더 읽기 쉽게 만들었습니다 실제 애플리케이션의 경우, 이는 큰 이익을 가져올 것입니다