티스토리 뷰
개요
Slack slash command 를 사용할때에 HTTP POST reqeust 를 통해 보내주는 내용이 궁금하다
그것을 Golang 으로 처리하는 방법을 알아보자. httprouter 를 사용하여 조금 코드를 변경하였다.
- GitHub 소스코드 위치 (현재 포스트 내용): https://github.com/nicewook/slack_slash_cmd/tree/master/version2
덤1. serveo 를 써보자. 개발시 로컬서버를 포트포워딩하여 ip에 도메인명을 할당해주는 서비스이다. https://serveo.net/
덤2. gin 을 써보자. nodejs 의 nodemon 처럼, 소스 변경시 자동으로 서버를 재실행하게 해준다. https://github.com/codegangsta/gin
* 지난번 포스팅의 내용중 일부를 수정하며 진행하였음 https://jusths.tistory.com/72
** 매우 유용했던 참고링크: https://goo.gl/Zc3b4Y
httprouter 사용
라우팅에서 대표적인 두 녀석을 비교해보면 gorilla/mux 는 조금 느리지만 기능이 많고, httprouter 는 빠르지만 기능이 몇 없다.
현재 구현은 라우팅이 많지 않기에 큰 의미는 없지만, httprouter 를 사용해 보았다.
|
1) import 해주고
import "github.com/julienschmidt/httprouter"
2) 생성해주고
r := httprouter.New()
3) 라우팅 해주면 된다.
- r.GET 와 r.POST 를 통해 - "/" 와 "/slash" 로 들어오면 - index() 함수와 slash.Handler() 함수를 수행해준다.
|
Slack slash command - HTTP POST
받은 것 그대로를 출력해보고, ParseForm() 을 해서 출력해보자.
TL;DR: ParseForm 을 해주면 비어있는 body 의 Form 과 PostForm 의 value 인 map 을 채워준다.
코드는 다음과 같다.
출력 결과를 보자
merge tool 로 비교해 보았다. 왼쪽이 받은 것 그대로, 오른쪽이 ParseForm() 을 적용한 것이다.
헤드부터 바디 초반까지는 똑같다.
바뀌는 부분은 바디의 Form 과 PostForm 이다.
r.ParseForm() 을 먹여주니 이 두 key 값의 map 에 값이 들어가는 것이다.
r.ParseForm() 의 결과로 채워지는 Form 과 PostForm 도 비교해보자
- 두 맵은 정확히 같다. 맵은 순서가 없어서 라인의 위치는 조금 조정하였다.
* 참고. Slack 에서 보내준다고 했던 항목들과 일치한다 (omitempty 제외)
왜 똑같은 것을 두 개 채워줄까?
Form 의 경우는 URL 에 실려오는 query parameter 를 파싱한 값까지 들어가기 때문에 용도에 따라 둘을 나눠 쓰지 않나 싶다.
→ 하위 버전과의 호환 때문일 수도 있다.
- query 만 쓰는 경우와, query 와 body 모두를 파싱한 데이터를 이용하고 싶을때는 Form 을 이용
- body 로 들어온 데이터만 처리할 경우는 PostForm 을 이용
여기까지, 그리고 다음에는
- 이 포스팅에서는 Slack slash command 에서 보내오는 POST 를 Parsing 하는 법에 대해서 알아보았다.
- 다음에는 이를 통해서 Slack 에서온 message 인지 verify 하는 법을 알아볼까 한다.
덤1. serveo
지난 포스팅에서는 ngrok 을 소개했었는데, 이번에는 serveo 를 써본다. https://serveo.net/
로컬 서버의 ip 에 대해 domain 이 할당되기에 개발시에는 매번 domain 이 바뀌는 ngrok 보다 나은점이 있다.
조금 설명하자면, Slack 에서는
우리가 지정한 slash command 를 만나면 (여기선 /time)
우리가 지정한 서버의 주소로 HTTP POST request 를 날린다.
→ 이때, 우리가 실행시킨 로컬 서버로 보내지도록 외부에 노출된 주소를 만들어 주는 서비스이다.
사용법은 간단하다. 설치도 필요없다. 로컬서버에서 아래와 같이 치면 된다.
그러면 생성되는 주소를 Slack 에 알려주면 된다.
- "-R" 옵션은 ssh 의 port forwarding 옵션이다. - 첫 80은 외부에서 접근할 포트 - localhost:80 은 포트 포워딩을 원하는, 여기서는 나의 로컬서버의 주소와 포트 - serveo.net 은 실제 외부에서 바라볼 주소 (를 제공해주는 사이트인 serveo.net) → 그러면 serveo.net 은 요청이 들어온 IP 에 대해 특정 도메인을 할당해준다. 이것을 Slack 의 설정에 넣어주면 된다.
|
|
세세한 기능은 훨씬 많지만, 서비스의 timeout 으로 계속 끊기는 것을 방지하려면 아래와 같이 추가해주면 된다.
-o ServerAliveInterval 옵션은 serveo 에서 제공하는 것은 아니고, ssh 옵션이다.
|
ServerAliveInterval Sets a timeout interval in seconds after which if no data has been received from the server, ssh(1) will send a message through the encrypted channel to request a response from the server |
덤2. gin
링크: https://github.com/codegangsta/gin
nodejs 의 nodemon 처럼, 서버를 실행시켜두면,
go get github.com/codegangsta/gin 로 설치가 가능하며
로컬서버의 Port 가 80 이고, 실행시킬 파일명이 server2.go 이면 아래와 같이 실행하면 된다.
gin -i --appPort 80 run server2.go
이제부터 gin 이 실행된 폴더와 하위폴더에서 파일을 변경하면 즉시 build 및 재실행된다.
유용했던 참고링크:
Processing Form Request Data In Golang 의 요약 정리
- 원본링크: https://goo.gl/Zc3b4Y
HTTP Reqeust 의 header
- Server, Client 간에 주고 받는 정보이며 key, value 쌍들이다.
- 가장 대표적인 key 는 Content-Type 이다. 이를 통해 받는 쪽에서 Body 를 어떻게 처리 / 파싱할지 알 수 있다.
- JSON 이 선호되지만, HTML 의 영향으로 application/x-www-form-urlencoded 가 쓰이는 부분이 있다.
Content-Type |
종류 |
application/json |
JSON |
application/atom+xml |
XML |
application/pdf |
|
application/octet-stream |
Raw Stream |
application/x-www-form-urlencoded |
Form Data |
- url 에 붙여서 query parameter 로 데이터를 전송할 수도 있지만
- 중요하거나 민감한 데이터는 POST 를 통해 request body 에 넣어보내는 것이 맞다.
Parsing
Content-Type 이 application/x-www-form-urlencoded 라면, 일단 ParseForm() 을 먹여줘라.
- 만약 파일 업로드를 지원한다면 ParseMultipartForm() 을 쓴다.
r.Form 과 r.PostForm
- 공식문서를 챙겨보면 아래와 같다.
- https://golang.org/pkg/net/http/#Request.ParseForm
ParseForm() 은 r.Form 과 r.PostForm 을 값으로 채워준다.
1) 모든 HTTP request 에 대하여 - URL 의 raw query 를 파싱해서 r.Form 을 채워준다.
2) 그 중에서도 HTTP POST, PUT, PATCH 의 경우는 - request body 를 파싱해서 r.Form 과 r.PostForm 을 모두 채워준다. - 따라서, r.Form 에서는 raw query 와 request body 파싱한 값들이 모두 들어가게 되는데 reqeust body 의 파싱값이 우선한다. → POST, PUT, PATCH 가 아니거나 아예 Content-Type 이 application/x-www-form-urlencoded 가 아니라면 request body 를 읽지 않는다. - MaxBytesReader 가 설정되어 있지 않다면, request body 의 크기는 10MB 보다 작다. |
|
'golang' 카테고리의 다른 글
Slack slash command: Verifying requests from Slack (0) | 2019.02.19 |
---|---|
Golang Channel 의 자명한 이치 (Axioms) (0) | 2019.02.18 |
Slack slash command + Golang server (0) | 2019.02.12 |
time.Sleep, time.Duration (0) | 2019.02.11 |
Golang: Github - Travis-CI - Heroku (0) | 2019.02.07 |
- Total
- Today
- Yesterday
- bun
- go
- 영화
- 독서
- agile
- ChatGPT
- pool
- Shortcut
- 노션
- strange
- websocket
- Gin
- 독서후기
- notion
- github
- 2023
- intellij
- golang
- 제이펍
- 체호프
- 클린 애자일
- 잡학툰
- postgres
- solid
- OpenAI
- API
- folklore
- 인텔리제이
- JIRA
- Bug
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |