OpenJS Architect를 사용하여 서버 없는 전체 영화 추적기를 구축하는 방법 - 제1부분
우리 뭐 짓고 있어?
본고에서 저는 AWS 서버 없는 서비스를 사용하는 완전한 응용 프로그램의 시작을 소개할 것입니다. 이 응용 프로그램은 완전한 데이터베이스, 세션 지원, GitHub OAuth 로그인을 갖추고 개발할 때 점진적인 강화를 고려할 것입니다.이 프로그램은 로그인한 사용자에게 영화 목록을 제공합니다.모든 영화가 관람되었는지 여부를 밝히기 위해 검사를 받을 수 있다.그래서 네가 본 모든 Nic Cage 영화를 추적할 수 있어.
우리가 필요로 하는 도구
이 프로그램은 노드를 요구할 것입니다.js, OpenJS Architect, 당신이 가장 좋아하는 텍스트 편집기, 기본적인 자바스크립트 지식, 그리고 Git를 어떻게 사용하는지.오, GitHub 계정이 하나 더 있어요.
Architect는 AWS에서 서버 웹 응용 프로그램이 없는 소스 배포 프레임워크입니다.Lambda 함수, API 게이트웨이, DynamoDB를 설정할 때 복잡성을 많이 숨깁니다.
새 설계자 프로젝트를 만들고 시작할 때 CI/CD를 설정합니다.
시작하려면 아래 버튼을 클릭하여 15초 이내에 배포하십시오.
GitHub 자격 증명에 로그인하여 사용하기 시작하면 계정에 새 재구매 계약이 만들어집니다.당신의 CI/CD가 완성되었습니다!기본 분기에 제출할 때마다 staging
환경이 새로 생성됩니다.
로컬에서 시작하려면 복제 재구매 및 실행 npm i
을 실행하십시오.
코드, 응용 프로그램의 기초 구조로 삼다.원호형 줄app.arc
파일을 보고 다음과 같이 수정합니다.
@app
example-movie-tracker
@static
@http
get /
get /login
post /logout
post /watched
@tables
data
scopeID *String
dataID **String
ttl TTL
app.arc
파일을 수정한 후 명령줄에서 arc init
을 실행하여 함수를 구축합니다.
GitHub OAuth 및 환경 변수
이제 GitHub OAuth를 실현해 봅시다.우리는 환경 변수를 설정하고 일부 파일을 수정해야 한다.
환경 변수를 사용하면 타사 API 키와 URL 같은 민감한 상태를 응용 프로그램 코드에 하드코딩하지 않고도 매개 변수화할 수 있습니다.
우선, follow these instructions에 새 OAuth 프로그램을 등록하십시오.다음을 확인해야 합니다.
프로젝트 루트 디렉토리의 GITHUB_CLIENT_ID
, GITHUB_CLIENT_SECRET
및 GITHUB_REDIRECT
파일에 저장해야 합니다.구조자는 파일을 읽고 런타임 시 환경 변수를 Lambda에 로드합니다.파일은 다음과 같습니다.
#prefs.arc
@env
testing
GITHUB_CLIENT_ID <your-client-id>
GITHUB_CLIENT_SECRET <your-client-secret>
GITHUB_REDIRECT http://localhost:3333/login
이것은 prefs.arc
을 실행하여 현지에서 일할 수 있도록 합니다.배포된 어플리케이션에서 실행하려면 npm start
과 staging
에 새 OAuth 어플리케이션을 만들고 Begin 콘솔에서 새로운 환경 변수 세트를 업데이트해야 합니다.
OAuth 로그인 흐름 구현
이제 GitHub의 OAuth 로그인 흐름을 처리하기 위해 코드를 작성할 수 있습니다.
우선, 우리는 production
함수를 작성할 것이다.
// src/http/get-login/index.js
const arc = require('@architect/functions')
const github = require('./github')
exports.handler = arc.http.async(login)
async function login(req) {
let account
if (req.query.code) {
try {
account = await github(req)
} catch (err) {
return {
statusCode: err.code,
body: err.message
}
}
return {
session: { account },
location: '/'
}
} else {
return {
location: '/'
}
}
}
이 get-login
함수는 GitHub 응용 프로그램이 성공적으로 검증된 후 리디렉션된 위치입니다.
만약 우리가 성공적으로 신분 검증을 진행한다면, 되돌아오는 코드를 사용하여 GitHub의 API에서 계정 데이터를 검색할 수 있습니다.
이 프로그램은 노드를 요구할 것입니다.js, OpenJS Architect, 당신이 가장 좋아하는 텍스트 편집기, 기본적인 자바스크립트 지식, 그리고 Git를 어떻게 사용하는지.오, GitHub 계정이 하나 더 있어요.
Architect는 AWS에서 서버 웹 응용 프로그램이 없는 소스 배포 프레임워크입니다.Lambda 함수, API 게이트웨이, DynamoDB를 설정할 때 복잡성을 많이 숨깁니다.
새 설계자 프로젝트를 만들고 시작할 때 CI/CD를 설정합니다.
시작하려면 아래 버튼을 클릭하여 15초 이내에 배포하십시오.
GitHub 자격 증명에 로그인하여 사용하기 시작하면 계정에 새 재구매 계약이 만들어집니다.당신의 CI/CD가 완성되었습니다!기본 분기에 제출할 때마다 staging
환경이 새로 생성됩니다.
로컬에서 시작하려면 복제 재구매 및 실행 npm i
을 실행하십시오.
코드, 응용 프로그램의 기초 구조로 삼다.원호형 줄app.arc
파일을 보고 다음과 같이 수정합니다.
@app
example-movie-tracker
@static
@http
get /
get /login
post /logout
post /watched
@tables
data
scopeID *String
dataID **String
ttl TTL
app.arc
파일을 수정한 후 명령줄에서 arc init
을 실행하여 함수를 구축합니다.
GitHub OAuth 및 환경 변수
이제 GitHub OAuth를 실현해 봅시다.우리는 환경 변수를 설정하고 일부 파일을 수정해야 한다.
환경 변수를 사용하면 타사 API 키와 URL 같은 민감한 상태를 응용 프로그램 코드에 하드코딩하지 않고도 매개 변수화할 수 있습니다.
우선, follow these instructions에 새 OAuth 프로그램을 등록하십시오.다음을 확인해야 합니다.
프로젝트 루트 디렉토리의 GITHUB_CLIENT_ID
, GITHUB_CLIENT_SECRET
및 GITHUB_REDIRECT
파일에 저장해야 합니다.구조자는 파일을 읽고 런타임 시 환경 변수를 Lambda에 로드합니다.파일은 다음과 같습니다.
#prefs.arc
@env
testing
GITHUB_CLIENT_ID <your-client-id>
GITHUB_CLIENT_SECRET <your-client-secret>
GITHUB_REDIRECT http://localhost:3333/login
이것은 prefs.arc
을 실행하여 현지에서 일할 수 있도록 합니다.배포된 어플리케이션에서 실행하려면 npm start
과 staging
에 새 OAuth 어플리케이션을 만들고 Begin 콘솔에서 새로운 환경 변수 세트를 업데이트해야 합니다.
OAuth 로그인 흐름 구현
이제 GitHub의 OAuth 로그인 흐름을 처리하기 위해 코드를 작성할 수 있습니다.
우선, 우리는 production
함수를 작성할 것이다.
// src/http/get-login/index.js
const arc = require('@architect/functions')
const github = require('./github')
exports.handler = arc.http.async(login)
async function login(req) {
let account
if (req.query.code) {
try {
account = await github(req)
} catch (err) {
return {
statusCode: err.code,
body: err.message
}
}
return {
session: { account },
location: '/'
}
} else {
return {
location: '/'
}
}
}
이 get-login
함수는 GitHub 응용 프로그램이 성공적으로 검증된 후 리디렉션된 위치입니다.
만약 우리가 성공적으로 신분 검증을 진행한다면, 되돌아오는 코드를 사용하여 GitHub의 API에서 계정 데이터를 검색할 수 있습니다.
app.arc
파일을 보고 다음과 같이 수정합니다.@app
example-movie-tracker
@static
@http
get /
get /login
post /logout
post /watched
@tables
data
scopeID *String
dataID **String
ttl TTL
app.arc
파일을 수정한 후 명령줄에서 arc init
을 실행하여 함수를 구축합니다.GitHub OAuth 및 환경 변수
이제 GitHub OAuth를 실현해 봅시다.우리는 환경 변수를 설정하고 일부 파일을 수정해야 한다.
환경 변수를 사용하면 타사 API 키와 URL 같은 민감한 상태를 응용 프로그램 코드에 하드코딩하지 않고도 매개 변수화할 수 있습니다.
우선, follow these instructions에 새 OAuth 프로그램을 등록하십시오.다음을 확인해야 합니다.
프로젝트 루트 디렉토리의 GITHUB_CLIENT_ID
, GITHUB_CLIENT_SECRET
및 GITHUB_REDIRECT
파일에 저장해야 합니다.구조자는 파일을 읽고 런타임 시 환경 변수를 Lambda에 로드합니다.파일은 다음과 같습니다.
#prefs.arc
@env
testing
GITHUB_CLIENT_ID <your-client-id>
GITHUB_CLIENT_SECRET <your-client-secret>
GITHUB_REDIRECT http://localhost:3333/login
이것은 prefs.arc
을 실행하여 현지에서 일할 수 있도록 합니다.배포된 어플리케이션에서 실행하려면 npm start
과 staging
에 새 OAuth 어플리케이션을 만들고 Begin 콘솔에서 새로운 환경 변수 세트를 업데이트해야 합니다.
OAuth 로그인 흐름 구현
이제 GitHub의 OAuth 로그인 흐름을 처리하기 위해 코드를 작성할 수 있습니다.
우선, 우리는 production
함수를 작성할 것이다.
// src/http/get-login/index.js
const arc = require('@architect/functions')
const github = require('./github')
exports.handler = arc.http.async(login)
async function login(req) {
let account
if (req.query.code) {
try {
account = await github(req)
} catch (err) {
return {
statusCode: err.code,
body: err.message
}
}
return {
session: { account },
location: '/'
}
} else {
return {
location: '/'
}
}
}
이 get-login
함수는 GitHub 응용 프로그램이 성공적으로 검증된 후 리디렉션된 위치입니다.
만약 우리가 성공적으로 신분 검증을 진행한다면, 되돌아오는 코드를 사용하여 GitHub의 API에서 계정 데이터를 검색할 수 있습니다.
#prefs.arc
@env
testing
GITHUB_CLIENT_ID <your-client-id>
GITHUB_CLIENT_SECRET <your-client-secret>
GITHUB_REDIRECT http://localhost:3333/login
이제 GitHub의 OAuth 로그인 흐름을 처리하기 위해 코드를 작성할 수 있습니다.
우선, 우리는
production
함수를 작성할 것이다.// src/http/get-login/index.js
const arc = require('@architect/functions')
const github = require('./github')
exports.handler = arc.http.async(login)
async function login(req) {
let account
if (req.query.code) {
try {
account = await github(req)
} catch (err) {
return {
statusCode: err.code,
body: err.message
}
}
return {
session: { account },
location: '/'
}
} else {
return {
location: '/'
}
}
}
이 get-login
함수는 GitHub 응용 프로그램이 성공적으로 검증된 후 리디렉션된 위치입니다.만약 우리가 성공적으로 신분 검증을 진행한다면, 되돌아오는 코드를 사용하여 GitHub의 API에서 계정 데이터를 검색할 수 있습니다.
get-login
req.query.code
모듈을 만듭니다.이 github.js
은 GitHub에서 계정 데이터를 검색하는 데 사용됩니다.// src/http/get-login/github.js
const tiny = require('tiny-json-http')
module.exports = async function github(req) {
try {
let result = await tiny.post({
url: 'https://github.com/login/oauth/access_token',
headers: { Accept: 'application/json' },
data: {
code: req.query.code,
client_id: process.env.GITHUB_CLIENT_ID,
client_secret: process.env.GITHUB_CLIENT_SECRET,
redirect_url: process.env.GITHUB_REDIRECT
}
})
let token = result.body.access_token
let user = await tiny.get({
url: `https://api.github.com/user`,
headers: {
Authorization: `token ${token}`,
Accept: 'application/json'
}
})
return {
token,
name: user.body.name,
login: user.body.login,
id: user.body.id,
url: user.body.url,
avatar: user.body.avatar_url
}
} catch (err) {
return {
error: err.message
}
}
}
다음에, 우리는 github.js
함수에auth 구성 요소를 만들 것이다// src/http/get-index/index.js
const arc = require('@architect/functions')
exports.handler = arc.http.async(http)
function authControl(account) {
if (account && account.name) {
return `
Welcome back ${account.name}
<form action=/logout method="post">
<button>Logout</button>
</form>`
} else {
let clientID = process.env.GITHUB_CLIENT_ID
let redirectURL = process.env.GITHUB_REDIRECT
let href = `https://github.com/login/oauth/authorize?client_id=${clientID}&redirect_url=${redirectURL}`
return `
<a href='${href}'>Login with GitHub</a>
`
}
}
async function http (req) {
return {
html: `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Praise Cage</title>
</head>
<body>
<h1>Praise Cage</h1>
${ authControl(req.session.account) }
</body>
</html>
`
}
}
현재 우리는 세션 대상을 지우고 사용자를 취소할 수 있는 get-index
프로세서를 만들 수 있습니다.// src/http/post-logout/index.js
let arc = require('@architect/functions')
async function logout(req) {
return {
session: {},
location: '/'
}
}
exports.handler = arc.http.async(logout)
테스트 인증
현재 우리는 post-logout
을 실행하여 현지에서 우리의 응용 프로그램을 테스트할 수 있다.GitHub 자격 증명을 사용하여 로그인할 수 있는 링크가 표시되어야 합니다.
우리 npm 가동 노선 구축
이제 UI를 계속 구축할 때입니다.우리는 데이터베이스에 있는 모든 단점에서 데이터를 얻을 것이다.
// src/http/get-index/index.js
let arc = require('@architect/functions')
let data = require('@begin/data')
exports.handler = arc.http.async(http)
function authControl(account) {
if (account && account.name) {
return `
Welcome back ${account.name}
<form action=/logout method="post">
<button>Logout</button>
</form>`
} else {
let clientID = process.env.GITHUB_CLIENT_ID
let redirectURL = process.env.GITHUB_REDIRECT
let href = `https://github.com/login/oauth/authorize?client_id=${clientID}&redirect_url=${redirectURL}`
return `
<a href='${href}'>Login with GitHub to see a list of movies</a>
`
}
}
function movie({ key, watched, title }) {
return `<form action="/watched" method="post">
<input type="hidden" name="movieId" value="${key}">
<input type="checkbox" name=watched ${ watched? 'checked' : ''}>
${title}
<button>Save</button>
</form>`
}
async function getMovies(account) {
let movies = [
{key: '001', title: 'Raising Arizona'},
{key: '002', title: 'Con Air'},
{key: '003', title: 'National Treasure'},
]
if (account) {
let accountMovies = await data.get({
table: `${account.id}-movies`
})
console.log('found account movies', accountMovies)
let result = ''
for (let mov of movies) {
let found = !!(accountMovies.find(m=> m.key === mov.key))
result += movie({key: mov.key, title: mov.title, watched: found })
}
return result
}
return ''
}
async function http (req) {
return {
html: `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Praise Cage</title>
</head>
<body>
<h1>Praise Cage</h1>
${ authControl(req.session.account) }
${ await getMovies(req.session.account) }
<script src=/_static/index.js type=module></script>
</body>
</html>
`
}
}
우리는 두 가지 함수를 추가했다. 그것이 바로 get-index
과 get-index
이다.이러한 함수는 일부 매개변수를 적용하고 HTML 문자열을 반환합니다.이러한 기능 구성 요소를 사용하여 더 큰 프레임워크 없이 UI를 구축할 수 있습니다.
getMovies를 사용하여 본 영화를 DynamoDB에 저장
우리는 movies
을 DynamoDB 클라이언트로 사용하여 본 영화를 모든 사용자의 계정에 저장합니다.
// src/http/post-watched/index.js
const arc = require('@architect/functions')
const data = require('@begin/data')
exports.handler = arc.http.async(route)
async function route(req) {
console.log('post-watched:', req.body)
let account = req.session.account.id
if (req.body.watched) {
await data.set({
table: `${account}-movies`,
key: req.body.movieId
})
} else {
await data.destroy({
table: `${account}-movies`,
key: req.body.movieId
})
}
return {
location: '/'
}
}
다음 섹션에서는 클라이언트 자바스크립트를 사용하는 방법에 대해 설명합니다.이 웹 사이트는 JavaScript가 비활성화된 경우에도 작동하도록 단계적으로 강화할 것입니다.
Reference
이 문제에 관하여(OpenJS Architect를 사용하여 서버 없는 전체 영화 추적기를 구축하는 방법 - 제1부분), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/pchinjr/how-to-build-a-full-stack-serverless-movie-tracker-with-openjs-architect-part-1-2gj3
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
이제 UI를 계속 구축할 때입니다.우리는 데이터베이스에 있는 모든 단점에서 데이터를 얻을 것이다.
// src/http/get-index/index.js
let arc = require('@architect/functions')
let data = require('@begin/data')
exports.handler = arc.http.async(http)
function authControl(account) {
if (account && account.name) {
return `
Welcome back ${account.name}
<form action=/logout method="post">
<button>Logout</button>
</form>`
} else {
let clientID = process.env.GITHUB_CLIENT_ID
let redirectURL = process.env.GITHUB_REDIRECT
let href = `https://github.com/login/oauth/authorize?client_id=${clientID}&redirect_url=${redirectURL}`
return `
<a href='${href}'>Login with GitHub to see a list of movies</a>
`
}
}
function movie({ key, watched, title }) {
return `<form action="/watched" method="post">
<input type="hidden" name="movieId" value="${key}">
<input type="checkbox" name=watched ${ watched? 'checked' : ''}>
${title}
<button>Save</button>
</form>`
}
async function getMovies(account) {
let movies = [
{key: '001', title: 'Raising Arizona'},
{key: '002', title: 'Con Air'},
{key: '003', title: 'National Treasure'},
]
if (account) {
let accountMovies = await data.get({
table: `${account.id}-movies`
})
console.log('found account movies', accountMovies)
let result = ''
for (let mov of movies) {
let found = !!(accountMovies.find(m=> m.key === mov.key))
result += movie({key: mov.key, title: mov.title, watched: found })
}
return result
}
return ''
}
async function http (req) {
return {
html: `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Praise Cage</title>
</head>
<body>
<h1>Praise Cage</h1>
${ authControl(req.session.account) }
${ await getMovies(req.session.account) }
<script src=/_static/index.js type=module></script>
</body>
</html>
`
}
}
우리는 두 가지 함수를 추가했다. 그것이 바로 get-index
과 get-index
이다.이러한 함수는 일부 매개변수를 적용하고 HTML 문자열을 반환합니다.이러한 기능 구성 요소를 사용하여 더 큰 프레임워크 없이 UI를 구축할 수 있습니다.getMovies를 사용하여 본 영화를 DynamoDB에 저장
우리는 movies
을 DynamoDB 클라이언트로 사용하여 본 영화를 모든 사용자의 계정에 저장합니다.
// src/http/post-watched/index.js
const arc = require('@architect/functions')
const data = require('@begin/data')
exports.handler = arc.http.async(route)
async function route(req) {
console.log('post-watched:', req.body)
let account = req.session.account.id
if (req.body.watched) {
await data.set({
table: `${account}-movies`,
key: req.body.movieId
})
} else {
await data.destroy({
table: `${account}-movies`,
key: req.body.movieId
})
}
return {
location: '/'
}
}
다음 섹션에서는 클라이언트 자바스크립트를 사용하는 방법에 대해 설명합니다.이 웹 사이트는 JavaScript가 비활성화된 경우에도 작동하도록 단계적으로 강화할 것입니다.
Reference
이 문제에 관하여(OpenJS Architect를 사용하여 서버 없는 전체 영화 추적기를 구축하는 방법 - 제1부분), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/pchinjr/how-to-build-a-full-stack-serverless-movie-tracker-with-openjs-architect-part-1-2gj3
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
// src/http/post-watched/index.js
const arc = require('@architect/functions')
const data = require('@begin/data')
exports.handler = arc.http.async(route)
async function route(req) {
console.log('post-watched:', req.body)
let account = req.session.account.id
if (req.body.watched) {
await data.set({
table: `${account}-movies`,
key: req.body.movieId
})
} else {
await data.destroy({
table: `${account}-movies`,
key: req.body.movieId
})
}
return {
location: '/'
}
}
Reference
이 문제에 관하여(OpenJS Architect를 사용하여 서버 없는 전체 영화 추적기를 구축하는 방법 - 제1부분), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/pchinjr/how-to-build-a-full-stack-serverless-movie-tracker-with-openjs-architect-part-1-2gj3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)