서버리스 아키텍처 소셜미디어 개발기 7편

서버리스 아키텍처 소셜미디어 개발기 7편

대망의 마지막 편입니다.

서버리스 아키텍처 소셜미디어 개발기 6편
_나프다 발표 이후 한참 글이 뜸했네요. 이제 점점 끝이 보입니다. 속도를 내야겠네요 사용자 스토리4 1. 김개발은 아침 스탠드업 시간에 같이 이야기를 나눌 수 있는 주제를 위해 스탠드업이라는 웹 앱을 찾아간다. …_techstory.shma.so

지난 편에 이어 계속 하겠습니다.

우린 모두 한 그룹이니까요~

1\. 김개발은 아침 스탠드업 시간에 같이 이야기를 나눌 수 있는 주제를 위해 스탠드업이라는 웹 앱을 찾아간다. 이렇게 함으로써 사람들과 IT에 대한 주제로 커뮤니케이션을 할 수 있다.  
2\. 김개발이 사이트를 방문해서 자신이 어제 유심하게 읽은 글을 올릴 수 있다. 이렇게 하면 다른 사람들이 볼 수 있다.  
\* 에디터 창에 인터넷 링크를 입력하면 자동적으로 페이지 카드가 만들어 진다. 이 때 페이지 링크는 oEmbed를 써서 동작하는데 웹 표준을 준수하고 자연스러워야 한다.  
\* 에디터 창은 하나만 있고 거기서 글을 작성하고 업로드 하면 글이 외부 클라우드 공간에 저장이 된다.

3\. 김개발이 작성한 글이 목록으로 보여진다. 이렇게 함으로써 다른 사람들이 목록을 확인할 수 있다.  
4\. 김개발은 google ID를 가지고 로그인을 할 수 있다. 이렇게 함으로써 내가 쓴 글만 따로 모아서 볼 수 있다.**  
5\. 김개발은 그룹 별로 스탠드업을 만들 수 있고 각 그룹별고 글을 올릴 수 있다**
`</pre>

그룹 기능을 넣고 나서는 내가 이럴려고 계속한다 했나 자괴감 들어.라는 순간이 몇번이나 왔는지 모르겠습니다. 이유는 몇가지가 있는데 첫번째는 처음 설계를 몇번이나 바꿔야 하는 것이며 , 두 번째는 테스트 코드가 어느 순간 동작하지 않는 것이었습니다. 설계를 바꾸는 것은 개발의 숙명이라 받아들일 수 있었는데 테스트 코드는 어느 순간 놓치고 나니 TDD를 진행하지 못한 부분이 있어 많이 부끄러워 지더군요.

본론으로 들어가서 이번 글에는 유저스토리를 하나 더 추가해 보았습니다. “**김개발은 그룹을 만들 수 있고 각 그룹별고 글을 올릴 수 있다.” **이 내용을 토대로 어떻게 들어갔는지 한번 살펴 보도록 하겠습니다.

#### [](http://keen.devpools.kr/2017/02/01/%5B2017-02-01%2010:29:09%5D%E1%84%89%E1%85%A5%E1%84%87%E1%85%A5%E1%84%85%E1%85%B5%E1%84%89%E1%85%B3%20%E1%84%8B%E1%85%A1%E1%84%8F%E1%85%B5%E1%84%90%E1%85%A6%E1%86%A8%E1%84%8E%E1%85%A5%20%E1%84%89%E1%85%A9%E1%84%89%E1%85%A7%E1%86%AF%E1%84%86%E1%85%B5%E1%84%83%E1%85%B5%E1%84%8B%E1%85%A5%20%E1%84%80%E1%85%A2%E1%84%87%E1%85%A1%E1%86%AF%E1%84%80%E1%85%B5%207%E1%84%91%E1%85%A7%E1%86%AB/#0-%EA%B3%A0%EC%B9%A9%EB%8B%88%EB%8B%A4 "0\. 고칩니다")0\. 고칩니다

이전에 firebase-ui 때문에 외부에 소스를 뺀 적이 있죠? 시간은 어느덧 두달이 지났으니 당연히 npm으로 등록이 되었습니다. 나프다 발표하는 당일에 추가가 되기는 했었습니다.

<pre>`$npm install firebase firebaseui --save
`</pre>

#### [](http://keen.devpools.kr/2017/02/01/%5B2017-02-01%2010:29:09%5D%E1%84%89%E1%85%A5%E1%84%87%E1%85%A5%E1%84%85%E1%85%B5%E1%84%89%E1%85%B3%20%E1%84%8B%E1%85%A1%E1%84%8F%E1%85%B5%E1%84%90%E1%85%A6%E1%86%A8%E1%84%8E%E1%85%A5%20%E1%84%89%E1%85%A9%E1%84%89%E1%85%A7%E1%86%AF%E1%84%86%E1%85%B5%E1%84%83%E1%85%B5%E1%84%8B%E1%85%A5%20%E1%84%80%E1%85%A2%E1%84%87%E1%85%A1%E1%86%AF%E1%84%80%E1%85%B5%207%E1%84%91%E1%85%A7%E1%86%AB/#1-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-%EC%A0%84%EC%97%90 "1\. 시작하기 전에")1\. 시작하기 전에

![](https://cdn-images-1.medium.com/max/1600/1*OlvH8Q0PNeY0IZpiFELC8g.jpeg)그림1

그림 1과 같은 역할을 하는 UI를 먼저 만들어 보려고 합니다. 기본 UI 기능은 그룹을 선택해야 할 수 있어야 하고 그룹을 만들 수 있어야 합니다. 그래서 선택을 할 수 있는 회전목마(Carousel) UI가 필요하고 그룹을 만들 수 있는 UI도 필요해서 새 그룹이라는 버튼을 달아 두었습니다.

#### [](http://keen.devpools.kr/2017/02/01/%5B2017-02-01%2010:29:09%5D%E1%84%89%E1%85%A5%E1%84%87%E1%85%A5%E1%84%85%E1%85%B5%E1%84%89%E1%85%B3%20%E1%84%8B%E1%85%A1%E1%84%8F%E1%85%B5%E1%84%90%E1%85%A6%E1%86%A8%E1%84%8E%E1%85%A5%20%E1%84%89%E1%85%A9%E1%84%89%E1%85%A7%E1%86%AF%E1%84%86%E1%85%B5%E1%84%83%E1%85%B5%E1%84%8B%E1%85%A5%20%E1%84%80%E1%85%A2%E1%84%87%E1%85%A1%E1%86%AF%E1%84%80%E1%85%B5%207%E1%84%91%E1%85%A7%E1%86%AB/#2-%EA%B7%B8%EB%A3%B9-%EB%A7%8C%EB%93%A4%EA%B8%B0 "2\. 그룹 만들기")2\. 그룹 만들기

그룹을 만들기 위해서는 당연히 기존의 firebase 에 저장된 스키마에 대한 조정이 필요하겠죠?

![](https://cdn-images-1.medium.com/max/1600/1*sSrIpCI61RQLXqUo1oReFg.jpeg)posts 생긴 형태

기존의 posts라는 스키마에는 모든 글이 저장되고 이 내용을 읽어와서 작업을 했었는데, 이제는 group 별로 조정할 일들이 생겼습니다.

![](https://cdn-images-1.medium.com/max/1600/1*p3_WoYtd7UWa4l3E1wrgMQ.jpeg)기존의 posts는 더 이상 필요가 없다.

groups는 그룹을 만들면 생성될 수 있는 엔트리가 될 것이고 group-posts에 각 그룹 별로 아티클이 들어갈 수 있도록 작업을 할 것입니다. 먼저 그룹을 생성하고 리스트 하는 작업을 해 보겠습니다. 생성을 하려면 다음과 같은 UI를 통해 그룹간 이동을 할 수 있습니다.

![](https://cdn-images-1.medium.com/max/1600/1*sVIaS0JmBfItOazHLlQURQ.jpeg)

일단 이 일련의 작업들을 하는 세가지 버튼을 만들어 보겠습니다. 먼저 그룹 페이지에 처음 들어오게 되면 그룹에 해당하는 이미지가 보여지고 그룹 작업을 선택하면(1) 새 그룹을 만들 수 있어야 하며(3), 다른 그룹을 선택할 수도(4) 있어야 합니다. 글 쓰기 버튼을 선택하면(2) 글 쓰기를 할 수 있는 에디터가 나와서 글이 작성되어야 하며 여러가지 모든 상황에서 원래 그룹으로 원상복귀(5)할 수 도 있어야 합니다.

어떤 작업을 먼저 하면 좋을까요? **React 개발에 있어서는 state를 어떻게 관리할 것인가** 를 첫번째 질문으로 가져가야 할 것입니다. 외부에서 URL 기반으로 타이핑해서 들어올 때 처음 형태를 어떻게 가져야 할지를기준으로 설계를 해 보겠습니다.

1.  기존의 edit를 하던 부분을 URL로 처리했던 부분은 그렇게 중요하지 않을 것입니다.
2.  내부에서 선택 버튼을 누를 경우는 URL이 변경되어야 합니다.
3.  글쓰기 를 작성하면 URL은 변경되지 않지만 버튼의 state는 변경되어야 합니다.

![](https://cdn-images-1.medium.com/max/1600/1*W6HXkcZHcGVkR9-5GLaelQ.jpeg)

먼저 세가지 버튼에 대해서 상태를 유지하고 그 값에 따라 아래 Action Bar를 선택하도록 해 보겠습니다.

![](https://cdn-images-1.medium.com/max/1600/1*X5npSzmjYIiumCvSHl-wzA.jpeg)상태에 따라 색도 변하도록 설계하자버튼 선택에 따라 state 가 바뀌고, 변수 선택에 따른 컴포넌트 렌더링이 달라지게 설계!

버튼을 클릭하면 selectedButton 즉 선택한 버튼을 확인하게 되고 그에 따라서 CSS 값을 변경해 주는 작업을 하는 컴포넌트입니다. 이걸 가능하게 하기 위해서 actions, reducers 폴더 밑에 각각 Button.js파일을 만들었습니다.

<pre>`//ActionBar를 그려준다. 안드로이드의 액션바와는 다르다. 액션바와는...  
{**this**.renderActionBar(selectedButton)}

//그룹이 존재하고 버튼선택이 된 경우  
{groupName &amp;&amp; !selectedButton&amp;&amp;  
&lt;div style={{width:'100%',height:150,position:'relative'}}\&gt;  
&lt;img src={logoUrl} alt={groupName} style={{width:'100%',height:150}}/\&gt;  
&lt;div className=&quot;style\_title&quot; style={{width:"100%"}}\&gt;{groupName}&lt;/div\&gt;  
&lt;/div\&gt;  
}
`</pre>

renderActionBar는 ActionBar 가 선택된 버튼에 따라서 다르게 그려지도록 했고 어떤 버튼도 선택되지 않을 경우에는 그룹의 로고 URL을 보여주도록합니다.

**2.1\. 그룹 만들기**

자, 그럼 그룹은 어떻게 만들까요?

![](https://cdn-images-1.medium.com/max/1600/1*AaIZeG2Tpgf58IMmPG_H5A.jpeg)파일 업로드가 시급하다.

그룹명이 존재하는지 (1)중복 확인을 한 후에 (2)드래그앤 드롭을 통한 파일 업로드, (3)그룹생성 의 순서대로 이루어집니다.

이중 1,3번의 Group의 Real Time DB에 대한 DAO는 여기서 다루지 않겠습니다. (소스에서 확인하세요.) 드래그앤 드롭해서 파일 업로드 하는 부분만 확인을 하면 Firebase의 FileUpload에 대한 인터페이스와 Dropzone UI 에 대한 이야기로 나눠서 볼 수 있을 거 같습니다.

**Firebase FileUpload**

src 폴더 아래 FileUtil.js를 만들었습니다.

주목 하셔야 할 부분은 다음의 storageRef 입니다.

<pre>`//storageRef 정의  
var storageRef = firebase.storage().ref();

**// 업로드  
var **uploadTask = storageRef.child(&apos;images/&apos; + file.name).put(file, metadata);

// 이벤트 정의

uploadTask.on(firebase.storage._TaskEvent_.STATE\_CHANGED,....(중략)
`</pre>

그럼 이 부분을 호출한 부분을 살펴 볼까요?

**Dropzone**

src 파일 밑에 GroupAdd.js 라는 파일을 만들었습니다. 이 파일에서 중요하게 눈여겨 보실 부분은 react-dropzone이라는 라이브러리를 이용했다는 점이고 그 부분은 소스의 처음 import 부분에 포함이 되어 있습니다.

<pre>`&lt;Dropzone onDrop={(acceptedFiles, rejectedFiles)=\&gt;**this**.onDrop} accept=&quot;image/\*&quot; className=&quot;drop-file padding-top&quot;\&gt;  
&lt;div\&gt;파일을 드래그앤 드롭 하거나 클릭해서 선택하세요&lt;/div\&gt;  
&lt;/Dropzone\&gt;
`</pre>

Dropzone 에서 onDrop이라는 이벤트를 만들었고 이 이벤트는 기본적으로 허용된 파일과 거절된 파일을 인자로 받아서 처리해 줍니다.

<pre>`onDrop (acceptedFiles, rejectedFiles) {

...  
**if**(acceptedFiles &amp;&amp; acceptedFiles.length\&gt;0){  
**...**  
imageUpload(acceptedFiles, 1, (downloadUrl)=\&gt;{  
**this**.setState({  
groupImage:downloadUrl,  
isSpin: **false  
**});  
});  
}**else**{  
...  
}  
}
`</pre>

#### [](http://keen.devpools.kr/2017/02/01/%5B2017-02-01%2010:29:09%5D%E1%84%89%E1%85%A5%E1%84%87%E1%85%A5%E1%84%85%E1%85%B5%E1%84%89%E1%85%B3%20%E1%84%8B%E1%85%A1%E1%84%8F%E1%85%B5%E1%84%90%E1%85%A6%E1%86%A8%E1%84%8E%E1%85%A5%20%E1%84%89%E1%85%A9%E1%84%89%E1%85%A7%E1%86%AF%E1%84%86%E1%85%B5%E1%84%83%E1%85%B5%E1%84%8B%E1%85%A5%20%E1%84%80%E1%85%A2%E1%84%87%E1%85%A1%E1%86%AF%E1%84%80%E1%85%B5%207%E1%84%91%E1%85%A7%E1%86%AB/#3-%EC%A1%B0%ED%9A%8C%ED%95%98%EA%B8%B0 "3\. 조회하기")3\. 조회하기

이렇게 그룹을 만들고 났으면 URL 별로 그룹이 조회가 되도록 내용을 추가해 줍니다. 스키마에 대해서는 서두에 밝혔으니 소스코드 레벨로만 간단하게 설명하겠습니다. (FirebaseDAO에 대해서는 이미 수차례 설명했으니 소스코드도 최대한 짧게 가겠습니다.)

reducer는 생략하고 action만 살펴보고 넘어가겠습니다.

<pre>`**export function **groupSelect(groupName){  
**return **(dispatch) =\&gt; {  
dao.getGroup(groupName).once(&apos;value&apos;, (snapshot) =\&gt; {  
**if**(snapshot.val()) {  
**let **logoUrl = snapshot.val().logoUrl;  
dispatch(getGroup(groupName, logoUrl));  
dispatch(selectButton());  
}  
})  
}  
}  
**export function **getGroup(groupName, logoUrl){  
**return **(dispatch) =\&gt; {  
dao.listGroupArticle(groupName).then((articles)=\&gt;dispatch(getArticle(articles,groupName,logoUrl)));  
}  
}
`</pre>

소스코드 처럼 group을 가지고 와서 로고 및 데이타를 가져온 뒤에 버튼을 선택하는 액션을 다시한번 연결하고는 끝이 납니다.

라우터 소스는 그에 따라 아래와 같이 간단해 졌습니다.

<pre>`&lt;Provider store={store}\&gt;  
&lt;Router history={history}\&gt;  
&lt;Route path=&quot;/&quot; component={App}\&gt;  
&lt;Route path=&quot;login&quot; component={Login}/\&gt;  
&lt;Route path=&quot;groups/:groupName&quot; /\&gt;  
&lt;Route path=&quot;\*&quot; component={NotFound}/\&gt;  
&lt;/Route\&gt;  
&lt;/Router\&gt;  
&lt;/Provider\&gt;

이렇게 그룹의 개념을 집어 넣어서 전체 내용을 다시한번 리마인드 하면서 전체에 대한 시리즈는 끝을 낼까 합니다.

지금까지는 실행에 대한 내용이었고 이후는 서버리스 아키텍처에 대한 고찰에 관한 이야기 + 리팩토링에 대한 이야기를 해 볼까 합니다.

그 동안 어려운 내용 같이 따라오신다고 고생하셨습니다.

소스코드는 아래 링크를 참고하시면 됩니다.

ehrudxo/standup
_standup project for newbi_github.com

By Keen Dev on February 1, 2017.

Exported from Medium on May 31, 2017.

공유하기