m.request()를 사용하여 서버에 요청 보내기 (mithril)

웹 애플리케이션이 서버와 통신할 때에는 form submit을 통해서 요청을 보내거나, XMLHttpRequst를 사용해서 비동기로 요청하는 방법이 있다. Mithril에서는 m.request()를 사용해서 보다 손쉽게 서버 통신을 처리할 수 있다.

기본적인 GET요청을 보내고 응답을 받는 방법

m.request() 에 요청을 보낼 주소와 부가적인 정보를 넘겨주면 응답을 처리할 수 있는 Promise 객체를 리턴받게 된다. 이때, 기본적으로 서버 응답은 JSON 형식으로 돌아오는 것을 가정하고, mithril은 JSON을 내부에서 파싱하여 자바스크립트 객체로 변환한 후 promise 객체에게 넘겨준다. 따라서 간단하게 다음과 같이 요청을 보내고 응답을 처리하는 방식으로 코드를 작성할 수 있다.

m.request({method: "GET", url: "/api/v1/users",)
  .then(users => console.log(users));

요청 주소 및 그외 정보는 다음과 같은 키를 사용해서 객체를 구성하여 전달하게 된다.

  • url : (필수) 요청 주소
  • method : 요청의 HTTP 메소드 타입. 생략시 GET으로 간주
  • data : 서버로 전송할 요청의 페이로드. GET요청인 경우에는 이 값은 쿼리스트링으로 변환되어 URL에 추가된다.
  • async: 비동기 요청여부. 기본값은 true
  • user, password : 인증을 위한 사용자 및 비밀번호 필드
  • withCredential: 제3자 도메인으로 쿠키 전송 여부. (기본값은 false)
  • config: xhr 객체를 처리할 함수를 설정. 흔히 프로그레스바를 구현할 때 사용
  • headers: HTTP 헤더를 자바스크립트 객체 형식으로 지정
  • type: 특정한 클래스를 지정하면, 응답값을 전달해서 해당 타입으로 변환한다.
  • extract: xhr 객체나 options 객체를 받아서 값을 추출하는 함수를 변경할 수 있다.
  • useBody: GET 요청시 data 값을 URL 파라미터가 아닌 payload로 강제 전송한다.
  • serialize: 요청 데이터를 직렬화하는 방법. 기본적으로 JSON으로 변환한다.
  • deserialize: 응답 데이터를 역직렬화하는 방법. 기본적으로 JSON을 기대하기 때문에 파일을 전송받으려는 경우 변경해주어야 한다.
  • background: 기본값은 false이며, true로 설정한 경우 통신이 끝난 후에 redraw()를 호출하지 않는다.

예제 : 파일 업로드 구현

mithril을 사용하지 않더라도 비동기 파일 업로드는 폼데이터 객체를 생성해서 해당 데이터를 POST로 서버에 전달하는 것으로 구현하면 된다. m.request()를 사용할 때에도 폼데이터를 생성하는 것은 동일하다. 대신 폼 업로드의 경우에는 요청 정보를 JSON으로 변환하지 않으므로 serialize 옵션을 따로 지정해줘야 한다. 다음 코드는 파일 선택 버튼을 페이지에 추가하고, 파일을 선택했을 때 해당 파일을 업로드하는 액션을 구현한 것이다.

const upload = (e) => {
    let file = e.target.files[0];
    let data = new FormData();
    data.append('file', file);
    m.request({
        method: "POST", 
        url: "/api/v1/upload", 
        data: data, 
        serialize: (v) => v
    });
};

m.render(document.body, 
    m("input[type=file]", {onchange: upload})
);

예제: 업로드 과정 표시하기

요청 옵션의 config 키를 사용하여, xhr 객체에 대한 이벤트처리를 할 수 있다. progress 이벤트가 발생할 때마다 진행률을 계산해서 화면에 업데이트할 때의 대략의 예를 보이면 다음과 같다.

function foo(e) {
	var data = new FormData();
	data.append(e.target.files[0]);
	m.request({
		method: "POST",
		url: "/api/upload",
		body: data,
		config: (xhr) => {
			xhr.upload.addEventListener("progress", (e) => {
				progress = e.loaded / e.total * 100
				// force to redraw
				m.redraw()
			})
		}
	}).then((res) => console.log(res))
}

예제: 파일 다운로드

파일을 업로드하는 것과 마찬가지로, 파일을 가져오는 동작 역시, deserialize 옵션을 주어 파일 정보를 JSON으로 파싱하지 않도록해주면 된다. 여기서는 svg 파일을 읽어오는데, m.trust() 함수를 사용해서 이를 바로 DOM 요소로 만들어서 화면에 그릴 수 있다.

// load svg and render it
m.request({mothod:"GET", url:"/files/icon.svg", deserialize:(v)=>v})
    .then(it => m.render(document.body, m.trust(it)));

연관 글

  • mithril 앱의 기본 구성과 m()
  • 가상 DOM 렌더링하기
  • 마운팅과 렌더링
  • 양방향 바인딩과 이벤트 처리
  • 컴포넌트
  • 라우팅
  • m.request()를 사용하여 서버에 요청 보내기 (mithril)
  1.  mithril 앱의 기본 구성 및 m()
  2.  m.render() – 가상 DOM 렌더링하기
  3. m.mount – 가상 노드를 마운트하기
  4. m.prop() – 양방향 바인딩을 위한 데이터 래퍼 – deprecated
  5. m.withAttr() 이벤트 핸들러 처리
  6. m.component – 가상노드를 컴포넌트로 사용하기
  7. Todo 앱 예제
  8. m.route() – 단일페이지 애플리케이션 및 라우팅 규칙
  9. m.request – 서버와의 통신

Read more

워드프레스에서 고스트로 이전

워드프레스에서 고스트로 이전

이 글을 쓰면서도 믿기 힘든 사실인데, 블로그라는 걸 처음 시작한지가 20년이 되었습니다. 이글루스에서 처음 시작했다가, SK컴즈가 인수한다고 발표함과 동시에 워드프레스로 플랫폼을 옮겼죠. 워드프레스오 옮긴 이후에는 호스팅 환경을 이리 저리 옮기긴 했지만 거의 18년 가까이 워드프레스를 사용해온 것 같습니다. 그 동안 워드프레스는 블로깅 툴에서 명실상부한 범용CMS로 발전했습니다. 사실 웬만한 홈페이지들은 이제

By sooop
띄어쓰기에 대한 생각

띄어쓰기에 대한 생각

업무 메일을 쓸 때 가장 많이 쓰는 말 중에 하나가 메일 말미에 ‘업무에 참고 부탁 드립니다.‘인데요, 어느 날부터 아웃룩에서 이 ‘부탁 드립니다’가 틀렸다고 맞춤법 지적을 하기 시작했습니다. 맞는 말은 ‘부탁드립니다’라고 붙여 쓰는 거라고. 사실 아래아한글 시절부터 이전의 MS워드까지, 워드프로세서들의 한국어 맞춤법 검사 실력은 거의 있으나 마나 한

By sooop

구글 포토에서 아이클라우드로 탈출한 후기

한 때 구글 포토가 백업 용량을 무제한으로 제공해 주겠다고해서, 구글 포토를 사용해서 사진을 백업해왔습니다. 물론 이 이야기의 결말은 저나 이 글을 읽고 있는 여러분이나 모두 알고 있습니다. 사실 AI에게 학습 시킬 이미지 데이터를 모으기 위한 것일 뿐이라거나 하는 이야기는 그 당시에도 있었습니다만, 에이 그래도 구글인데 용량은 넉넉하게 주겠지…하는 순진한

By sooop

Julia의 함수 사용팁

연산자의 함수적 표기 Julia의 연산자는 기본적으로 함수이며, 함수 호출 표기와 같은 방식으로 호출하는 것이 가능합니다. 또한 그 자체로 함수이기 때문에 filter(), map() 과 같이 함수를 인자로 받는 함수에도 연산자를 그대로 적용하는 것이 가능합니다. 특히 + 연산자는 sum() 함수와 같이 여러 인자를 받아 인자들의 합을 구할 수 있습니다. 2 + 3 # = 5 +(2,

By sooop