네온은 이제 Azure 마켓플레이스에서 이용 가능합니다. Neon과 Azure 간의 새로운 통합을 통해 Neon 구독과 청구를 Azure 포털을 통해 관리할 수 있게 되었습니다. Azure 서버리스와 Neon은 자연스러운 조합입니다 — Azure 서버리스는 웹 서버 인프라를 관리하지 않아도 되게 해줍니다. Neon은 데이터 분기 및 벡터 데이터베이스 확장과 같은 추가 기능을 제공하여 데이터베이스도 동일한 역할을 합니다.
그렇다면, Neon, Azure 서버리스, 그리고 Node.js를 사용하여 URL 단축 API를 작성해보며 이 새로운 통합을 시도해 보겠습니다.
참고: 터미널, VS Code와 Node v22 이상이 설치되어 있어야 합니다.
인프라 설정하기
오늘은 조금 역방향으로 작업해야 합니다. 코드를 작성하기 전에 서버리스 함수와 데이터베이스를 먼저 설정할 것입니다.
단계 1. Azure 웹 포털을 엽니다. 만약 계정이 없다면 Microsoft 계정을 생성해야 합니다.
단계 2. Azure에 계정이 없다면 구독을 생성해야 합니다. 이는 Azure에서 할 수 있습니다.
단계 3. 이제 서버리스 함수와 데이터베이스를 저장할 리소스 그룹을 만들 수 있습니다. Azure의 새 리소스 그룹 페이지로 이동하여 다음과 같이 양식을 작성하십시오:
- 리소스 그룹이 “AzureNeonURLShortener”로 설정되고 위치가 West US 3로 설정된 Azure 리소스 그룹 생성 페이지입니다.
- 일반적으로 사용자 및 사용자에 가장 가까운 위치를 사용하십시오. 위치는 서버리스 함수의 기본 배치와 가장 낮은 지연 시간을 가진 지역을 결정합니다. 이 예에서는 중요하지 않지만, 다른 위치를 사용하려는 경우 드롭다운을 통해 검색할 수 있습니다. 그러나 모든 이러한 지역에 Neon이 위치하고 있지 않다는 점을 유의하십시오. 이는 데이터베이스를 서버리스 함수와 더 멀리 둬야 한다는 것을 의미합니다.
단계 4. 아래의 “검토 및 생성”을 클릭하여 구성 검토 페이지에 액세스하십시오. 그런 다음 다시 “생성”을 클릭하십시오.
단계 5. 이제 서버리스 함수를 만들 수 있습니다. 불행히도, 다른 양식이 포함되어 있습니다. Azure Flex 소비 서버리스 앱 생성 페이지로 이동하여 양식을 작성하십시오. 이전에 만든 리소스 그룹을 사용하고 고유한 서버리스 함수 이름을 선택하고 함수를 리소스 그룹 위치에 배치하고 Node v20을 사용하십시오.
단계 6. 서버리스 앱에 선택한 이름은 API에 액세스할 수 있는 Azure의 서브도메인이 될 것이므로 신중하게 선택하십시오. 모든 항목을 작성한 후에 “검토 및 작성”을 클릭하고 마지막으로 “만들기”를 클릭하십시오. Azure가 새 앱 페이지로 리디렉션해야 합니다. 이제 Neon을 설정할 수 있습니다. Azure 포털에서 새 Neon 리소스 페이지를 열고, 양식을 작성하십시오.
Azure에서 Neon 데이터베이스 만드는 방법
단계 1. “AzureURLNeonShortener”를 리소스 그룹으로, “URLShortenerDB”를 리소스 이름으로, “서부 미국 3″를 위치로 하는 새 Neon 리소스 페이지를 만듭니다. 선택한 지역이 사용 불가능한 경우, 가장 가까운 지역을 선택하십시오. 모든 것을 완료한 후에 “검토 및 만들기”를 클릭하고 이전 리소스와 마찬가지로 “만들기”를 클릭하십시오.
단계 2. Neon 데이터베이스가 생성될 때까지 잠시 기다려야 할 수 있습니다. 생성되면 구성 페이지를 열고 “Neon으로 이동”을 클릭하십시오.
단계 3. 로그인 페이지로 리디렉션됩니다. Neon이 Azure 정보에 액세스하도록 허용하고 나면 프로젝트 생성 페이지에 자신을 찾게 될 것입니다. 아래 양식을 작성하십시오:
프로젝트와 데이터베이스 이름은 중요하지 않지만 데이터베이스를 Azure 서부 미국 3(또는 선택한 지역)에 위치시키십시오. 이렇게 하면 데이터베이스 쿼리가 데이터 센터를 떠나지 않아 대기 시간이 감소합니다.
단계 4. 페이지 하단의 “생성”을 클릭하여 기본 자동 스케일링 구성을 유지합니다. 이제 네온 데이터베이스 페이지로 리디렉션됩니다. 이 페이지에는 코드에서 데이터베이스에 연결하는 데 필요한 연결 문자열이 포함되어 있습니다. 연결 문자열을 복사하려면 “스니펫 복사”를 클릭하십시오.
나중에 필요하므로이를 잃지 않도록하십시오. 그러나 지금은 데이터베이스를 구조화해야합니다.
단계 5. 측면 탐색에서 “SQL 편집기”를 클릭하고 다음 SQL을 붙여 넣습니다:
CREATE TABLE IF NOT EXISTS urls(id char(12) PRIMARY KEY, url TEXT NOT NULL);
그런 다음 “실행”을 클릭하십시오. 이렇게하면 URL을 저장하는 데 사용할 테이블이 생성됩니다. 테이블은 매우 간단합니다. 기본 키 ID는 URL을 참조하는 데 사용할 12자리의 무작위 문자열이고 URL은 URL 자체를 저장할 가변 길이 문자열입니다.

단계 6. 측면 탐색의 테이블 보기를 확인하면 “urls” 테이블이 표시됩니다. 마지막으로 연결 문자열을 가져와야합니다. 측면 탐색의 “대시 보드”를 클릭하여 연결 문자열을 찾고 “스니펫 복사”를 클릭하십시오.
이제 코드 작성을 시작할 수 있습니다.
API 구축
단계 1. 먼저 Azure의 서버리스 CLI를 설치해야합니다. 이 CLI를 사용하면 프로젝트를 만들고 테스트/게시하는 데 도움이됩니다. 터미널을 열고 다음을 실행하십시오:
npm install -g azure-functions-core-tools --unsafe-perm true
단계 2. Yarn이나 pnpm과 같은 다른 패키지 관리자를 사용하려면 npm
을 선호하는 패키지 관리자로 교체하십시오. 이제 실제 프로젝트를 시작할 수 있습니다. 프로젝트를 만들 폴더를 열고 다음 세 명령을 실행하십시오:
func init --javascript
func new --name submit --template "HTTP trigger"
func new --name url --template "HTTP trigger"
npm install nanoid @neondatabase/serverless
이제 해당 폴더에 새로운 Azure 프로젝트가 생성된 것을 볼 수 있어야 합니다. 첫 번째 명령은 프로젝트를 생성하고, 다음 두 개의 명령은 서버리스 API 라우트를 생성하며, 마지막 명령은 데이터베이스와 인터페이스하기 위한 Neon 서버리스 드라이버와 ID 생성을 위한 Nano ID를 설치합니다. 우리는 Neon 드라이버 대신 표준 Postgres 드라이버를 사용할 수 있지만, Neon의 드라이버는 일회성 쿼리에 대한 대기 시간을 줄이기 위해 상태 없는 HTTP 쿼리를 사용합니다. 우리는 단일 요청을 처리하고 단일 쿼리를 전송할 수 있는 서버리스 함수를 실행하고 있기 때문에, 일회성 쿼리의 대기 시간이 중요합니다.
src/functions의 코드를 중점적으로 살펴보세요. 여기서 우리의 라우트를 찾을 수 있습니다. 그곳에 submit.js와 redirect.js라는 두 개의 파일이 있어야 합니다.
submit.js
submit.js는 URL을 제출하는 데 사용하는 코드를 저장할 것입니다. 먼저, submit.js를 열고 그 코드를 다음으로 교체하세요:
import { app } from "@azure/functions";
import { neon } from "@neondatabase/serverless";
import { nanoid } from "nanoid";
const sql = neon("[YOUR_POSTGRES_CONNECTION_STRING]");
app.http("submit", {
methods: ["GET"],
authLevel: "anonymous",
route: "submit",
handler: async (request, context) => {
if (!request.query.get("url"))
return {
body: "No url provided",
status: 400,
};
if (!URL.canParse(request.query.get("url")))
return {
body: "Error parsing url",
status: 400,
};
const id = nanoid(12);
await sql`INSERT INTO urls(id,url) VALUES (${id},${request.query.get(
"url"
)})`;
return new Response(`Shortened url created with id ${id}`);
},
});
이제 단계별로 나누어 보겠습니다. 먼저, Azure 함수 API, Neon 서버리스 드라이버 및 Nano ID를 가져옵니다. 우리는 여기서 CommonJS 대신 ESM (ES 모듈)을 사용하고 있습니다. 이를 지원하기 위해 나중에 몇 가지 변경을 해야 합니다.
다음으로, 데이터베이스와의 연결을 생성합니다. [YOUR_POSTGRES_CONNECTION_STRING]
을 Neon 대시보드에서 복사한 문자열로 교체하세요. 보안상의 이유로, 프로덕션 환경에서는 Azure Key Vault와 같은 서비스를 사용하여 키를 관리하는 것이 좋지만, 지금은 스크립트에 그냥 넣어 두는 것으로 충분합니다.
이제 실제 경로에 있습니다. 처음 몇 가지 속성은 경로 핸들러가 언제 트리거되어야 하는지 정의합니다: 이 경로가 submit에 대한 GET 요청에 의해 트리거되길 원합니다.
저희 핸들러는 매우 간단합니다. 먼저 URL이 URL 쿼리 매개변수를 통해 전달되었는지 확인합니다(예: /submit?url=https://google.com). 그런 다음, 새 URL.canParse API를 통해 유효한 URL인지 확인합니다. 그 다음으로, Nano ID로 ID를 생성합니다. ID가 12자이므로, 12를 Nano ID 생성기에 전달해야 합니다. 마지막으로, 새로운 ID 및 URL이 포함된 새 행을 데이터베이스에 삽입합니다. Neon 서버리스 드라이버는 쿼리를 자동으로 매개변수화하므로, 악의적인 사용자가 URL에 SQL 문을 전달하는 것에 대해 걱정할 필요가 없습니다.
redirect.js
redirect.js는 실제 URL 리다이렉션이 발생하는 곳입니다. 코드를 다음과 같이 대체하십시오:
import { app } from "@azure/functions";
import { neon } from "@neondatabase/serverless";
const sql = neon("[YOUR_POSTGRES_CONNECTION_STRING]");
app.http("redirect", {
methods: ["GET"],
authLevel: "anonymous",
route: "{id:length(12)}",
handler: async (request, context) => {
const url =
await sql`SELECT * FROM urls WHERE urls.id=${request.params.id}`;
if (!url[0]) return new Response("No redirect found", { status: 404 });
return Response.redirect(url[0].url, 308);
},
});
스크립트의 첫 부분은 submit.js와 동일합니다. 다시 한번, Neon 대시보드에서 복사한 문자열로 \[YOUR\_POSTGRES\_CONNECTION\_STRING\]
을 대체하십시오.
경로는 더 흥미로워집니다. 리다이렉트 ID가 될 수 있는 모든 경로를 수용해야 하므로, 12자로 제한된 매개변수를 사용합니다. 또한, 다른 12자 길이의 경로가 생길 경우 중첩될 수 있음에 유의하십시오. 그럴 경우, Azure 서버리스가 리다이렉트 경로를 다음에로드하도록 리다이렉트 경로의 이름을 Z로 시작하거나 다른 알파벳 수적으로 더 큰 문자로 변경할 수 있습니다.
마침내 실제 핸들러 코드를 가지게 되었습니다. 여기서 해야 할 일은 주어진 ID와 일치하는 URL을 쿼리하고 해당 URL이 있는 경우에는 해당 URL로 리디렉션하는 것입니다. 원본 단축 URL을 무시하도록 브라우저와 검색 엔진에 알리기 위해 리디렉트에 308 상태 코드를 사용합니다.
구성 파일
수정해야 할 사항이 두 가지 더 있습니다. 먼저 모든 함수에 /api
접두사를 추가하고 싶지 않습니다. 이를 제거하려면 프로젝트 디렉토리에 있어야 할 host.json 파일을 열고 다음을 추가하십시오:
"extensions": {
"http": {
"routePrefix": ""
}
}
이를 통해 라우트가 접두사 없이 작동할 수 있게 됩니다. 해야 할 마지막 일은 프로젝트를 ES 모듈로 전환하는 것입니다. package.json
을 열고 파일 끝에 다음을 삽입하십시오:
"type": "module"
그게 다입니다!
테스팅 및 배포
이제 func start
를 실행하여 로컬에서 테스트해 볼 수 있습니다. http://localhost:7071/submit?url=https://example로 이동한 다음 제공된 ID를 사용하여 http://localhost:7071/[YOUR_ID]로 이동하십시오. 그러면 example.com로 리디렉션됩니다.
물론 로컬에서만 실행할 수는 없습니다. 배포하려면 운영 체제에 따라 다음 명령 중 하나를 사용하여 Azure CLI를 설치해야 합니다:
macOS (Homebrew)
brew install azure-cli
Windows (WPM)
winget install -e --id Microsoft.AzureCLI
Linux
curl -L <https://aka.ms/InstallAzureCli> | bash
이제 터미널을 다시 시작하여 az login을 실행하고 프로젝트 디렉토리에서 다음을 실행하십시오.
func azure functionapp publish [FunctionAppName]
[FunctionAppName]
을(를) 앞서 함수에 지정한 이름으로 교체하십시오.
이제 [FunctionAppName].azurewebsites.net
에서 API에 액세스할 수 있어야합니다.
결론
이제 완전히 작동하는 URL 단축기를 갖게되었어야합니다. 코드에 액세스할 수 있고 프론트 엔드를 추가하는 작업을 할 수 있습니다. Neon 및 Azure의 기능에 대해 계속 읽고 싶다면 Branching을(를) 확인하는 것을 권장합니다. 어쨌든, 이 안내서에서 가치 있는 것을 배웠으면 좋겠습니다.
Source:
https://dzone.com/articles/build-url-shortener-neon-azure-serverless-functions