자바스크립트를 활성화 해주세요

p067 powershell Pode 서버로 Rest API 서비스하고 React에서 Ajax 출력하기

 ·  ☕ 2 min read

pode 를 사용하면 powershell로 rest api를 간단히 만들 수 있습니다. 퍼포먼스상으로는 문제가 있다고 생각하기 때문에 트랜잭션이 많은 production에서 사용한다라고 하면, 많이 생각해 봐야겠습니다만, 관리자용 툴로 사용한다면 안될 이유도 없을 것 같습니다.

이를 이용해서 react앱에서 표시해보면 어떨까요

pode 서비스

파워쉘의 아웃풋, 특히 윈도우즈에 특화된 서비스나 프로세스등을 REST API로 서비스해야하는 경우에는

  • pode 를 이용하여 Rest API를 서비스하는 것이,
  • node-powershell이나 pywinrm등과 같은 다른 언어로 wrap하는 것보다 훨씬 낫습니다.

전체적인 모습은 다음과 같습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import-module pode
Start-PodeServer {
    Add-PodeEndpoint -Address 127.0.0.1 -port 8080 -Protocol Http

    Add-PodeRoute -Method Get -Path '/api/services' -ScriptBlock {
        Write-PodeJsonResponse -Value (Get-Service | select Status,Name,DisplayName )
    }
}

New-NetFirewallRule -DisplayName "Allow inbound TCP port 8080" `
    -Direction inbound -LocalPort 8080 -Protocol TCP -Action Allow

실행화면은 다음과 같습니다.

p067_pode_service.png

클라이언트에서 테스트 화면

1
2
3
curl.exe http://localhost:8080/api/services
$res = curl http://localhost:8080/api/services
$res.Content

p067_pode_ise.png

react component

ServiceComponent? ServiceDiv? 컴퍼넌트 이름을 지을때 좋은 네이밍은 어떤것이 있나요? 우선 ServiceDiv로 했습니다.

ServiceDiv.tsx를 추가하고 다음과 같이 작성했습니다. 마운트하면서, ajax를 호출하는 거죠

 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
31
32
33
34
35
36
37
38
39
40
41
import React, {Component} from 'react';

interface IService { Status:string, Name:string, DisplayName:string }
const ServiceDivState = {content_service: []}

export class ServiceDiv extends Component {
    state = ServiceDivState;
    constructor(props:any) {
        super(props);
        this.state = ServiceDivState;
    }

    componentDidMount() {
        this.fetchResponse();
    }

    fetchResponse() {
        fetch('http://localhost:8080/api/services')
            .then(res => res.json())
            .then(res => {
                this.setState({
                    content_service: res
                });
            })
    }

    render() {
        return (
            <div>
                <h1>서비스</h1>
                <ul>
                    {this.state.content_service.map( (s:IService) => (
                        <li key={s.Name}>
                            <input type="text" defaultValue={s.DisplayName} />
                        </li>
                    ))}
                </ul>
            </div>
        );
    }
}

App.tsx

작성한 컴퍼넌트를 App 컴퍼넌트를 렌더링하는 부분에서 ServiceDiv를 함께 넣어줍니다.

1
<ServiceDiv/>

먼저 이렇게 써주고 Alt-Enter를 누루면 webstorm이 적당한 곳에 import문을 넣어줍니다.

1
import {ServiceDiv} from "./ServiceDiv";

CORS헤더 추가

아 서버사이드에 CORS 헤더를 추가하는 것을 잊었네요. 다음과 같이 수정해서 업데이트합니다.

1
2
3
4
5
6
7
8
9
Start-PodeServer {
    Add-PodeEndpoint -Address 127.0.0.1 -port 8080 -Protocol Http

    Add-PodeRoute -Method Get -Path '/api/services' -ScriptBlock {
        Add-PodeHeader -Name 'Access-Control-Allow-Origin' -Value '*'
        Add-PodeHeader -Name 'Access-Control-Allow-Methods' -Value '*'
        Write-PodeJsonResponse -Value (Get-Service | select Status,Name,DisplayName )
    }
}

실행하고 브라우저에서 확인한 모습은 다음과 같습니다.

p067_pode_browser.png

원하는 데이타는 Ajax를 통해 취득해 출력되었습니다만, 외관은 조금 수정이 필요할 것 같습니다.

이상으로 pode 서버로 Rest API 서비스를 제공하고 react ajax에서 이를 받아 출력해 보았습니다.

pode 서버가 퍼포먼스에서 조금 느릴 것이라고 생각했습니다만, (물론 csharp의 IIS 어플리케이션보다는 느리겠지만,) 체감상 매우 느리지는 않았습니다.

ref

공유하기

tkim
글쓴이
tkim
Software Engineer