【axios+SAM+API Gateway】localhost에서 api를 두드리게 되기 위해서 고생한 이야기
7771 단어 APIGatewayapi초보자AWS
소개
본고는 아래의 흐름에 따라, axios+SAM+API Gateway를 이용해, GET 및 POST 메소드의 API를 두드리는 곳까지를 목표로 하고 있습니다.
지난번 「로컬로부터 방금 작성한 API Gateway의 GET 메소드를 두드린다」라고 하는 것을 시도했습니다. 그 때, "도메인이 다른 경우는 CORS를 의식할 필요가 있다"는 것을 배웠습니다. 구체적으로는, API측에서 도메인간의 자원을 공유를 허가하는 것과 같은 내용을
header
에 포함해 반환할 필요가 있다, 라고 하는 것이었습니다.이번에는, 「로컬로부터 방금 작성한 API Gateway의 POST 메소드를 두드린다」라고 하는 것을 시도해 가고 싶습니다.
3. 로컬에서 방금 만든 API Gateway의 POST 메서드를 두드리기
그럼
POST
메소드를 두드릴 수 있도록 해 가고 싶습니다. 우선은 API측의 구현을 해 갑니다.POST
의 API로 다음 lambda
를 만듭니다.// post_item.py
import json
# import requests
def lambda_handler(event, context):
print(event)
msg = json.loads(event['body'])['message']
return {
"statusCode": 200,
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
},
"body": json.dumps({
"message": "you posted this message: " + msg
}),
}
또한 이
lambda
를 SAM
로 관리할 수 있도록 template.yaml
를 수정합니다.Resources:
PostItemFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: post_item/
Handler: post_item.lambda_handler
Runtime: python3.7
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /post_items
Method: post
그리고 이것들을 빌드 배치해 API측의 준비는 완료입니다.
이어서 앱 측을 수정합니다. 이번은
POST
메소드에 대응한 처리를 추가합니다.// App.js
import React, {Component} from 'react';
import axios from 'axios';
class App extends Component {
constructor(props){
super(props);
this.state = {
'appMessage': 'hello,app',
postApiMessage: 'before post'
};
this.doChange = this.doChange.bind(this);
this.getApi = this.getApi.bind(this);
this.postApiMessage = this.postApiMessage.bind(this);
}
instance = axios.create({
baseURL: 'https://flz1roclul.execute-api.ap-northeast-1.amazonaws.com/Prod'
});
doChange(e){
this.setState({
message: e.target.value
})
}
getApi(){
this.instance.get('/hello')
.then((response) => {
this.setState({
'appMessage': response.data['message']
})
})
.catch(() => {
this.setState({
'appMessage': 'faild get message from button'
})
})
}
postApiMessage(){
this.instance.post('/post_items', {'message': this.state.message})
.then((results)=>{
//console.log(results.json())
console.log(results)
this.setState({
'postApiMessage': 'postApiSuccess! ' + results.data['message']
})
})
.catch((results) => {
console.log(results)
this.setState({
'postApiMessage': 'postApiFailed' + results
})
})
}
render(){
return(
<div>
<p>{this.state.postApiMessage}</p>
<form>
<input type="text" value={this.state.message} onChange={this.doChange}/>
<input type="button" value="post api" onClick={this.postApiMessage} />
</form>
<div>{this.state.appMessage}</div>
<input type='button' onClick={this.getApi} value="button" />
</div>
)
}
}
export default App;
이번 처리는 앱 측에서 게시한 내용을 API 측에서 붙여 반환하는 단순한 것입니다.
전회의 반성을 살려, 이번은 API측에 필요한 header를 미리 추가해 두었으므로, 괜찮다고 생각합니다!
음...
무엇이 속지 않았습니까?
이번 오류 메시지는 다음과 같습니다.
Access to XMLHttpRequest at 'https://{APIのURL}/Prod/post_items' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
'Access-Control-Allow-Origin'
라고 생각했지만, 이번 중요한 것은 다음 장소였습니다.Response to preflight request doesn't pass access control check
조사해 보면, 특정의 조건을 채우면(자), 실제의 메소드가 실행되기 전에
OPTIONS
메소드가 실행된다 (그러니까 preflight
) 같습니다. 그래서 이번에는 그것에 대응하는 메소드가 준비되어 있지 않았기 때문에, 에러가 되었다고.그래서 대책을 하려고 합니다. 메소드 부분은 필요한 header를 돌려주는 것만으로 좋기 때문에 이하와 같이 했습니다.
// post_item_options.py
import json
# import requests
def lambda_handler(event, context):
return {
"statusCode": 200,
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
},
"body": json.dumps({
"message": "this is the method to avoid cors for post method"
# "location": ip.text.replace("\n", "")
}),
}
그리고 이것을
template.yaml
에 추가합니다.Resources:
PostItemOptionsFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: post_item_options/
Handler: post_item_options.lambda_handler
Runtime: python3.7
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /post_items
Method: options
중요한 것은
POST
메소드와 Path는 같게 하는 것입니다. 이것은, preflight
메소드는 송신하려고 한 메소드에 대해서 날기 때문입니다.다시 시도
API 측을 수정했으므로 다시 시도해 보았습니다.
성공 post가 성공하고 메시지가 반환되었습니다!
끝에
안전한 API 환경을 구축하고 앱에서 GET
및 POST
API를 두드릴 수 있습니다. 「단지 URL과 메소드를 지정해 두드리면 좋다」라고 생각하고 있었으므로, 설마 header 운운으로 이렇게 빠진다고는 생각하지 않았습니다. 만약 본고가 같은 고민에 직면하고 있는 사람의 도움이 되면 다행입니다.
Reference
이 문제에 관하여(【axios+SAM+API Gateway】localhost에서 api를 두드리게 되기 위해서 고생한 이야기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/soana/items/a357dcb9ab84d609a343
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(【axios+SAM+API Gateway】localhost에서 api를 두드리게 되기 위해서 고생한 이야기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/soana/items/a357dcb9ab84d609a343텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)