Introduction#
GitHub this note shows
- Next.js 13 api route handler
- AWS SDK S3Client and PollyClient
- Deploy with Amplify hosting
- TODO: add cognito authentication
Setup Project#
Create a new Next.js project with latest Next.js version
npx create-app-next@latest
Install AWS SDK for S3 and Polly
npm install @aws-sdk/client-s3 @aws-sdk/polly-client
Install other dependencies, here is details of package.json file
{"name": "nextjs-polly-demo","version": "0.1.0","private": true,"scripts": {"dev": "next dev","build": "next build","start": "next start","lint": "next lint"},"dependencies": {"@aws-sdk/client-polly": "^3.344.0","@aws-sdk/client-s3": "^3.344.0","@types/node": "20.2.5","@types/react": "18.2.8","@types/react-dom": "18.2.4","autoprefixer": "10.4.14","axios": "^1.4.0","eslint": "8.41.0","eslint-config-next": "13.4.4","next": "13.4.4","postcss": "8.4.24","react": "18.2.0","react-dom": "18.2.0","tailwindcss": "3.3.2","typescript": "5.1.3","uuid": "^9.0.0"},"devDependencies": {"@types/uuid": "^9.0.1"}}
API Route Handler#
Project structure for api route handler
|--app|--api|--polly|--route.ts|--polly|--page.tsx|--global.css|--layout.tsx|--page.tsx|--public|--test.mp3|--package.json|--.eslint.json|--next.config.js|--tailwind.config.js|--tsconfig.json
Create a simple api handler (POST, and GET). This is very usefull
- Run at server side
- Call AWS services such as S3, Polly
The GET method
export async function GET(request: Request) {console.log("server receive get ", request);return NextResponse.json({ name: "haimtran get" });}
The POST method
export async function POST(request: Request) {const requestJson = await request.json();// call polly api herereturn NextResponse.json({ url: name });}
Polly Client#
Let try S3 client first, detail here
import { ListObjectsCommand, S3Client } from "@aws-sdk/client-s3";const s3Client = new S3Client({region: "us-east-1",// TODO: credentials via cogito identity pool id});// desconstruct inputconst listObject = async ({ bucketName }: { bucketName: string }) => {try {const res = await s3Client.send(new ListObjectsCommand({Bucket: bucketName,}));console.log(res);} catch (error) {console.log(error);}};
Then let create a Polly client
const pollyClient = new PollyClient({region: "ap-southeast-1",// TODO: credentials via cogito identity pool id});const synthesizeSpeed = async ({ message }: { message: string }) => {const response = await pollyClient.send(new SynthesizeSpeechCommand({Engine: "standard",LanguageCode: "en-US",OutputFormat: "mp3",Text: message,VoiceId: "Amy",}));
Synthesize speech from text, and save the Audio Stream output to a file
const audio = await response.AudioStream?.transformToByteArray();if (audio?.buffer) {fs.writeFileSync("hello.mp3", Buffer.from(audio.buffer));} else {console.log("error audio buffer");}// TODO write to S3if (response.AudioStream) {const blob = new Blob([response.AudioStream as Blob]);const url = URL.createObjectURL(blob);console.log(url);}
Troubleshooting#
Please pay attention to the function format, correct one is
export async function GET(request: Request) {console.log("server receive get ", request);return NextResponse.json({ name: "haimtran get" });}
Wrong one
export async function GET({ request }: { request: Request }) {console.log("server receive get ", request);return NextResponse.json({ name: "haimtran get" });}