Booster 프레임에서 구름 시뮬레이션💻🌩️
22625 단어 devopstypescriptnodewebdev
응용 프로그램을 개발할 때, 모든 데이터베이스, 클라우드 서비스, 또는 어떤 것의 세부 사항을 고려하고 싶지 않을 수도 있다.아마도 너는 나와 마찬가지로 수중의 기술/서비스의 모든 라이브러리나 SDK를 배우는 것을 싫어할 것이다.
이런 추상적인 덕분에, 당신은 증압기 개념(명령, 이벤트 등)을 사용하여 인코딩을 하고, 나머지 부분을 소홀히 하기만 하면 됩니다.그런데 밑에 무슨 일이 일어날까요?어디 보자👀
클라우드 및 로컬 개발
구름은 멋진 것이지만, 현지에서 개발하고 당신의 변화를 바로 보는 것보다 더 좋은 것은 무엇입니까?
그렇습니다. 어떤 것들은 특정 서비스의 작업 방식을 모의할 수 있습니다. 예를 들어 DynamoDB, 또는 누군가가 그들의 전체 Kubernetes 응용 프로그램을 실행할 수 있습니다. 예를 들어 MongoDB, MySQL, Redis 등입니다. 심지어 서버 프레임워크가 없으면 비교적 신속하게 응용 프로그램을 배치할 수 있지만 그 대가는 방대하고 난잡한 YAML 파일을 유지하는 것입니다.
일은 더욱 간단해야 한다. 너는 튼튼한 컴퓨터로 너의 응용 프로그램을 개발할 필요가 없다.
많은 이유들이 있지만, 그 외에, 내가 방금 묘사한 이유들, 사람들은 가장 간단한 방식으로 응용 프로그램을 작성하기로 결심했다. 아마도 express
서버나 비슷한 방식일 것이다.
만약 우리가 express
서버를 가지고 있다면, 우리가 구름 속의 응용 프로그램으로서는?이것은 현지 공급업체의 생각이다.
증압기 공급자가 현지에서 일하는 것을 실현하다
증압기 공급자를 실현하려면 두 개의 npm
패키지를 만들어야 합니다.
증압기 공급자를 실현하려면 두 개의
npm
패키지를 만들어야 합니다.framework-provider-<name of your environment>
- 이 패키지는 다음을 담당합니다.framework-provider-<name of your environment>-infrastructure
- 이 패키지는 다음을 담당합니다.deploy
함수를 제공합니다. 이 함수는 클라우드 공급자에 필요한 모든 자원을 설정하고 코드를 정확하게 업로드합니다. 그리고 nuke
함수를 제공합니다. 이 함수는 배치된 모든 내용을 삭제하거나start
함수를 제공합니다.이것은 내가 현지 공급업체에 사용할 것이다.framework-provider-local
framework-provider-local-infrastructure
express
을 Booster가 제공하는 단점으로 사용하고 nedb을 사용할 것입니다. 이것은 NoSQL 데이터베이스의 로컬 파일 시스템 구현입니다. API는 MongoDB와 매우 유사합니다.NoSQL 데이터베이스가 아닌 경우 SQLite에 해당합니다.첫 번째 가방을 실현하기 시작합시다.
공급자 인터페이스
Booster의 공급자 인터페이스는 일반적인 TypeScript 인터페이스로 다음과 같은 방법으로 구현되어야 합니다.
export const Provider = {
events: {
rawToEnvelopes: ...,
forEntitySince: ...,
latestEntitySnapshot: ...,
store: ...,
},
readModels: {
rawToEnvelopes: ...,
fetch: ...,
search: ...,
store: ...,
// ...
},
graphQL: {
rawToEnvelope: ...,
handleResult: ...,
},
api: {
requestSucceeded,
requestFailed,
},
// ...
}
기초를 실현하기 위해 rawToEnvelopes
부터 이 함수들은 클라우드 데이터 형식에서 증강형 데이터 형식으로 전환됩니다.
로컬 공급자의 경우 express
을 사용하여 처리하기 때문에 데이터는 원래대로 도착합니다.
export function rawEventsToEnvelopes(rawEvents: Array<unknown>): Array<EventEnvelope> {
return rawEvents as Array<EventEnvelope>
}
export function rawReadModelEventsToEnvelopes(rawEvents: Array<unknown>): Array<ReadModelEnvelope> {
return rawEvents as Array<ReadModelEnvelope>
}
rawToEnvelope
필드의 graphQL
함수에 대해 요청 ID, 연결 ID 또는 이벤트 유형과 같은 더 많은 정보를 요청으로부터 얻어야 합니다. 이러한 정보는 요청에 나타나기 때문에 작업을 간소화하기 위해 무시됩니다.
export async function rawGraphQLRequestToEnvelope(
request: express.Request
): Promise<GraphQLRequestEnvelope | GraphQLRequestEnvelopeError> {
return {
requestID: UUID.generate(), // UUID.generate() provided by Booster
eventType: 'MESSAGE',
connectionID: undefined,
value: request.body,
}
}
이러한 기능이 실현됨에 따라 우리는 이미 단점을 Booster에 연결했다. 지금은 데이터를 저장하고 검색하는 방법을 가르쳐야 한다.
로컬 데이터베이스 만들기
NedB를 사용하여 Booster 응용 프로그램 데이터를 저장하는 경우 먼저 초기화해야 합니다.Provider
과 동일한 파일에서 이 작업을 수행할 수 있습니다.
import * as DataStore from 'nedb'
import { ReadModelEnvelope, EventEnvelope } from '@boostercloud/framework-types'
const events: DataStore<EventEnvelope> = new DataStore('events.json')
const readModels: DataStore<ReadModelEnvelope> = new DataStore('read_models.json')
NeDB는 테이블마다 하나의 파일을 사용하기 때문에 DataStore
두 개를 만들어 상호작용을 합니다.
현재, 우리는 공급자가 필요로 하는 방법을 실현해야 한다. 예를 들어 store
:
async function storeEvent(event: EventEnvelope): Promise<void> {
return new Promise((resolve, reject) => {
events.insert(event, (err) => {
err ? reject(err) : resolve()
})
})
}
async function storeReadModel(readModel: ReadModelEnvelope): Promise<void> {
return new Promise((resolve, reject) => {
readModels.insert(readModel, (err) => {
err ? reject(err) : resolve()
})
})
}
유감스럽게도 NedB는 Promise
기반 API를 제공하지 않고 promisify
을 제대로 사용할 수 없기 때문에 수동으로 포장해야 합니다.실현은 매우 간단하다.
나머지 방법은 다음과 같은 적절한 질의를 수행하는 것입니다.
async function readEntityLatestSnapshot(
entityID: UUID,
entityTypeName: string
): Promise<EventEnvelope> {
const queryPromise = new Promise((resolve, reject) =>
this.events
.find({ entityID, entityTypeName, kind: 'snapshot' })
.sort({ createdAt: -1 }) // Sort in descending order
.exec((err, docs) => {
if (err) reject(err)
else resolve(docs)
})
)
}
다른 방법도 약간 혼란스러울 수 있지만 일부 경우에는 HTTP 응답 관리와 같은 상호작용을 하기도 합니다.
async function requestSucceeded(body?: any): Promise<APIResult> {
return {
status: 'success',
result: body,
}
}
async function requestFailed(error: Error): Promise<APIResult> {
const statusCode = httpStatusCodeFor(error)
return {
status: 'failure',
code: statusCode,
title: toClassTitle(error),
reason: error.message,
}
}
Provider
의 모든 방법을 실현한 후에 우리는 기본적으로 첫 번째 가방을 완성했고 우리는 인프라 시설 열차에 뛰어들 수 있다🚂
Express 서버로 모든 컨텐츠 연결Provider
과 같은 상황에서 귀하의 Infrastructure
대상은 하나의 인터페이스에 부합되어야 합니다. 우리의 예시에서 이 인터페이스는 모든 내용을 초기화하는 start
방법입니다.여기에서 express
서버를 만들고 프레임워크 핵심에서 제공하는 함수를 호출하여 Booster에 연결합니다.
먼저 express
서버를 초기화합니다.
export const Infrastructure = {
start: (config: BoosterConfig, port: number): void => {
const expressServer = express()
const router = express.Router()
const userProject: UserApp = require(path.join(process.cwd(), 'dist', 'index.js'))
router.use('/graphql', graphQLRouter(userProject))
expressServer.use(express.json())
expressServer.use(router)
expressServer.listen(port)
},
}
여기에서 모든 공공 증강 기능에 접근할 수 있도록 사용자의 응용 프로그램을 가져옵니다. (UserApp
유형을 입력하십시오.)
현재 유일한 단점은 /graphql
입니다. 이것이 바로 우리가 지금 설정해야 할 것입니다.
function graphQLRouter(userApp: UserApp) {
const router = express.Router()
this.router.post('/', async (req, res) => {
const response = await userApp.boosterServeGraphQL(req) // entry point
res.status(200).json(response.result)
})
}
이렇게 해서 우리는 사용자의 응용 프로그램에서 boosterServeGraphQL
으로 전화를 걸기만 하면 된다.
패키지를 제공하는 데 필요한 모든 방법을 제공했기 때문에 Booster는 모든 인프라 기능에 접근할 수 있습니다. 이 기능은 필요에 따라 사용할 수 있습니다. 더 많은 코드를 작성할 필요가 없습니다.🚀
이게 다야!
나는 아름다운 로그 메시지, 테스트, 더 많은 좋은 것들을 추가하는 등 현지 공급자를 개선하기 위해 계속 노력할 것이다😉, 하지만 Booster repo의 다음 폴더에서 항상 전체 코드를 볼 수 있습니다.
export const Provider = {
events: {
rawToEnvelopes: ...,
forEntitySince: ...,
latestEntitySnapshot: ...,
store: ...,
},
readModels: {
rawToEnvelopes: ...,
fetch: ...,
search: ...,
store: ...,
// ...
},
graphQL: {
rawToEnvelope: ...,
handleResult: ...,
},
api: {
requestSucceeded,
requestFailed,
},
// ...
}
export function rawEventsToEnvelopes(rawEvents: Array<unknown>): Array<EventEnvelope> {
return rawEvents as Array<EventEnvelope>
}
export function rawReadModelEventsToEnvelopes(rawEvents: Array<unknown>): Array<ReadModelEnvelope> {
return rawEvents as Array<ReadModelEnvelope>
}
export async function rawGraphQLRequestToEnvelope(
request: express.Request
): Promise<GraphQLRequestEnvelope | GraphQLRequestEnvelopeError> {
return {
requestID: UUID.generate(), // UUID.generate() provided by Booster
eventType: 'MESSAGE',
connectionID: undefined,
value: request.body,
}
}
NedB를 사용하여 Booster 응용 프로그램 데이터를 저장하는 경우 먼저 초기화해야 합니다.
Provider
과 동일한 파일에서 이 작업을 수행할 수 있습니다.import * as DataStore from 'nedb'
import { ReadModelEnvelope, EventEnvelope } from '@boostercloud/framework-types'
const events: DataStore<EventEnvelope> = new DataStore('events.json')
const readModels: DataStore<ReadModelEnvelope> = new DataStore('read_models.json')
NeDB는 테이블마다 하나의 파일을 사용하기 때문에 DataStore
두 개를 만들어 상호작용을 합니다.현재, 우리는 공급자가 필요로 하는 방법을 실현해야 한다. 예를 들어
store
:async function storeEvent(event: EventEnvelope): Promise<void> {
return new Promise((resolve, reject) => {
events.insert(event, (err) => {
err ? reject(err) : resolve()
})
})
}
async function storeReadModel(readModel: ReadModelEnvelope): Promise<void> {
return new Promise((resolve, reject) => {
readModels.insert(readModel, (err) => {
err ? reject(err) : resolve()
})
})
}
유감스럽게도 NedB는 Promise
기반 API를 제공하지 않고 promisify
을 제대로 사용할 수 없기 때문에 수동으로 포장해야 합니다.실현은 매우 간단하다.나머지 방법은 다음과 같은 적절한 질의를 수행하는 것입니다.
async function readEntityLatestSnapshot(
entityID: UUID,
entityTypeName: string
): Promise<EventEnvelope> {
const queryPromise = new Promise((resolve, reject) =>
this.events
.find({ entityID, entityTypeName, kind: 'snapshot' })
.sort({ createdAt: -1 }) // Sort in descending order
.exec((err, docs) => {
if (err) reject(err)
else resolve(docs)
})
)
}
다른 방법도 약간 혼란스러울 수 있지만 일부 경우에는 HTTP 응답 관리와 같은 상호작용을 하기도 합니다.async function requestSucceeded(body?: any): Promise<APIResult> {
return {
status: 'success',
result: body,
}
}
async function requestFailed(error: Error): Promise<APIResult> {
const statusCode = httpStatusCodeFor(error)
return {
status: 'failure',
code: statusCode,
title: toClassTitle(error),
reason: error.message,
}
}
Provider
의 모든 방법을 실현한 후에 우리는 기본적으로 첫 번째 가방을 완성했고 우리는 인프라 시설 열차에 뛰어들 수 있다🚂Express 서버로 모든 컨텐츠 연결Provider
과 같은 상황에서 귀하의 Infrastructure
대상은 하나의 인터페이스에 부합되어야 합니다. 우리의 예시에서 이 인터페이스는 모든 내용을 초기화하는 start
방법입니다.여기에서 express
서버를 만들고 프레임워크 핵심에서 제공하는 함수를 호출하여 Booster에 연결합니다.
먼저 express
서버를 초기화합니다.
export const Infrastructure = {
start: (config: BoosterConfig, port: number): void => {
const expressServer = express()
const router = express.Router()
const userProject: UserApp = require(path.join(process.cwd(), 'dist', 'index.js'))
router.use('/graphql', graphQLRouter(userProject))
expressServer.use(express.json())
expressServer.use(router)
expressServer.listen(port)
},
}
여기에서 모든 공공 증강 기능에 접근할 수 있도록 사용자의 응용 프로그램을 가져옵니다. (UserApp
유형을 입력하십시오.)
현재 유일한 단점은 /graphql
입니다. 이것이 바로 우리가 지금 설정해야 할 것입니다.
function graphQLRouter(userApp: UserApp) {
const router = express.Router()
this.router.post('/', async (req, res) => {
const response = await userApp.boosterServeGraphQL(req) // entry point
res.status(200).json(response.result)
})
}
이렇게 해서 우리는 사용자의 응용 프로그램에서 boosterServeGraphQL
으로 전화를 걸기만 하면 된다.
패키지를 제공하는 데 필요한 모든 방법을 제공했기 때문에 Booster는 모든 인프라 기능에 접근할 수 있습니다. 이 기능은 필요에 따라 사용할 수 있습니다. 더 많은 코드를 작성할 필요가 없습니다.🚀
이게 다야!
나는 아름다운 로그 메시지, 테스트, 더 많은 좋은 것들을 추가하는 등 현지 공급자를 개선하기 위해 계속 노력할 것이다😉, 하지만 Booster repo의 다음 폴더에서 항상 전체 코드를 볼 수 있습니다.
export const Infrastructure = {
start: (config: BoosterConfig, port: number): void => {
const expressServer = express()
const router = express.Router()
const userProject: UserApp = require(path.join(process.cwd(), 'dist', 'index.js'))
router.use('/graphql', graphQLRouter(userProject))
expressServer.use(express.json())
expressServer.use(router)
expressServer.listen(port)
},
}
function graphQLRouter(userApp: UserApp) {
const router = express.Router()
this.router.post('/', async (req, res) => {
const response = await userApp.boosterServeGraphQL(req) // entry point
res.status(200).json(response.result)
})
}
나는 아름다운 로그 메시지, 테스트, 더 많은 좋은 것들을 추가하는 등 현지 공급자를 개선하기 위해 계속 노력할 것이다😉, 하지만 Booster repo의 다음 폴더에서 항상 전체 코드를 볼 수 있습니다.
packages/framework-provider-local
packages/framework-provider-local-infrastructure
흔적을 새기다
Reference
이 문제에 관하여(Booster 프레임에서 구름 시뮬레이션💻🌩️), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/boostercloud/emulating-the-cloud-within-booster-framework-17o8텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)