Movatterモバイル変換


[0]ホーム

URL:


If you like SST,give it a star on GitHub!
SST GuideForumsChangelogNewsletter
21k

How to create a serverless GraphQL API with AWS AppSync

Edit this page • View history
This chapter has been archived and is no longer updated.View the current version of the guide.

In this example we’ll look at how to create anAppSync GraphQL API on AWS usingSST. We’ll be allowing our users to get, create, update, delete, and list notes.

We’ll be using SST’sLive Lambda Development. It allows you to make changes and test AppSync locally without having to redeploy.

Here is a video of it in action.

Requirements

Create an SST app

Change indicator Let’s start by creating an SST app.

$npx create-sst@latest--template=base/example graphql-appsync$cdgraphql-appsync$npminstall

By default, our app will be deployed to theus-east-1 AWS region. This can be changed in thesst.config.ts in your project root.

import{SSTConfig}from"sst";exportdefault{config(_input){return{name:"graphql-appsync",region:"us-east-1",};},}satisfiesSSTConfig;

Project layout

An SST app is made up of two parts.

  1. stacks/ — App Infrastructure

    The code that describes the infrastructure of your serverless app is placed in thestacks/ directory of your project. SST usesAWS CDK, to create the infrastructure.

  2. packages/functions/ — App Code

    The code that’s run when your API is invoked is placed in thepackages/functions/ directory of your project.

Setting up our infrastructure

Let’s start by defining our AppSync API.

Change indicator Replace thestacks/ExampleStack.ts with the following.

import{StackContext,Table,AppSyncApi}from"sst/constructs";exportfunctionExampleStack({stack}:StackContext){// Create a notes tableconstnotesTable=newTable(stack,"Notes",{fields:{id:"string",},primaryIndex:{partitionKey:"id"},});// Create the AppSync GraphQL APIconstapi=newAppSyncApi(stack,"AppSyncApi",{schema:"packages/functions/src/graphql/schema.graphql",defaults:{function:{// Bind the table name to the functionbind:[notesTable],},},dataSources:{notes:"packages/functions/src/main.handler",},resolvers:{"Query    listNotes":"notes","Query    getNoteById":"notes","Mutation createNote":"notes","Mutation updateNote":"notes","Mutation deleteNote":"notes",},});// Show the AppSync API Id and API Key in the outputstack.addOutputs({ApiId:api.apiId,APiUrl:api.url,ApiKey:api.cdk.graphqlApi.apiKey||"",});}

We are creating an AppSync GraphQL API here using theAppSyncApi construct. We are also creating a DynamoDB table using theTable construct. It’ll store the notes we’ll be creating with our GraphQL API.

Finally, we bind our table to our API.

Define the GraphQL schema

Change indicator Add the following topackages/functions/src/graphql/schema.graphql.

typeNote{id:ID!content:String!}inputNoteInput{id:ID!content:String!}inputUpdateNoteInput{id:ID!content:String}typeQuery{listNotes:[Note]getNoteById(noteId:String!):Note}typeMutation{createNote(note:NoteInput!):NotedeleteNote(noteId:String!):StringupdateNote(note:UpdateNoteInput!):Note}

Let’s also add a type for our note object.

Change indicator Add the following to a new file inpackages/functions/src/graphql/Note.ts.

typeNote={id:string;content:string;};exportdefaultNote;

Adding the function handler

To start with, let’s create the Lambda function that’ll be our AppSync data source.

Change indicator Replacepackages/functions/src/main.ts with the following.

importNotefrom"./graphql/Note";importlistNotesfrom"./graphql/listNotes";importcreateNotefrom"./graphql/createNote";importupdateNotefrom"./graphql/updateNote";importdeleteNotefrom"./graphql/deleteNote";importgetNoteByIdfrom"./graphql/getNoteById";typeAppSyncEvent={info:{fieldName:string;};arguments:{note:Note;noteId:string;};};exportasyncfunctionhandler(event:AppSyncEvent):Promise<Record<string,unknown>[]|Note|string|null|undefined>{switch(event.info.fieldName){case"listNotes":returnawaitlistNotes();case"createNote":returnawaitcreateNote(event.arguments.note);case"updateNote":returnawaitupdateNote(event.arguments.note);case"deleteNote":returnawaitdeleteNote(event.arguments.noteId);case"getNoteById":returnawaitgetNoteById(event.arguments.noteId);default:returnnull;}}

Now let’s implement our resolvers.

Create a note

Starting with the one that’ll create a note.

Change indicator Add a file topackages/functions/src/graphql/createNote.ts.

import{DynamoDB}from"aws-sdk";import{Table}from"sst/node/table";importNotefrom"./Note";constdynamoDb=newDynamoDB.DocumentClient();exportdefaultasyncfunctioncreateNote(note:Note):Promise<Note>{constparams={Item:noteasRecord<string,unknown>,TableName:Table.Notes.tableName,};awaitdynamoDb.put(params).promise();returnnote;}

Here, we are storing the given note in our DynamoDB table.

Change indicator Let’s install theaws-sdk package in thepackages/functions/ folder package that we are using.

$npminstallaws-sdk

Read the list of notes

Next, let’s write the function that’ll fetch all our notes.

Change indicator Add the following topackages/functions/src/graphql/listNotes.ts.

import{DynamoDB}from"aws-sdk";import{Table}from"sst/node/table";constdynamoDb=newDynamoDB.DocumentClient();exportdefaultasyncfunctionlistNotes():Promise<Record<string,unknown>[]|undefined>{constparams={TableName:Table.Notes.tableName,};constdata=awaitdynamoDb.scan(params).promise();returndata.Items;}

Here we are getting all the notes from our table.

Read a specific note

We’ll do something similar for the function that gets a single note.

Change indicator Create apackages/functions/src/graphql/getNoteById.ts.

import{DynamoDB}from"aws-sdk";import{Table}from"sst/node/table";importNotefrom"./Note";constdynamoDb=newDynamoDB.DocumentClient();exportdefaultasyncfunctiongetNoteById(noteId:string):Promise<Note|undefined>{constparams={Key:{id:noteId},TableName:Table.Notes.tableName,};const{Item}=awaitdynamoDb.get(params).promise();returnItemasNote;}

We are getting the note with the id that’s passed in.

Update a note

Now let’s update our notes.

Change indicator Add apackages/functions/src/graphql/updateNote.ts with:

import{DynamoDB}from"aws-sdk";import{Table}from"sst/node/table";importNotefrom"./Note";constdynamoDb=newDynamoDB.DocumentClient();exportdefaultasyncfunctionupdateNote(note:Note):Promise<Note>{constparams={Key:{id:note.id},ReturnValues:"UPDATED_NEW",UpdateExpression:"SET content = :content",TableName:Table.Notes.tableName,ExpressionAttributeValues:{":content":note.content},};awaitdynamoDb.update(params).promise();returnnoteasNote;}

We are using the id and the content of the note that’s passed in to update a note.

Delete a note

To complete all the operations, let’s delete the note.

Change indicator Add this topackages/functions/src/graphql/deleteNote.ts.

import{DynamoDB}from"aws-sdk";import{Table}from"sst/node/table";constdynamoDb=newDynamoDB.DocumentClient();exportdefaultasyncfunctiondeleteNote(noteId:string):Promise<string>{constparams={Key:{id:noteId},TableName:Table.Notes.tableName,};// await dynamoDb.delete(params).promise();returnnoteId;}

Note that, we are purposely disabling the delete query for now. We’ll come back to this later.

Let’s test what we’ve created so far!

Starting your dev environment

Change indicator SST features aLive Lambda Development environment that allows you to work on your serverless apps live.

$npm run dev

The first time you run this command it’ll take a couple of minutes to deploy your app and a debug stack to power the Live Lambda Development environment.

=============== Deploying app===============Preparing your SST appTranspiling sourceLinting sourceDeploying stacksdev-graphql-appsync-ExampleStack: deploying... ✅  dev-graphql-appsync-ExampleStackStack dev-graphql-appsync-ExampleStack  Status: deployed  Outputs:    ApiId: lk2fgfxsizdstfb24c4y4dnad4    ApiKey: da2-3oknz5th4nbj5oobjz4jwid62q    ApiUrl: https://2ngraxbyo5cwdpsk47wgn3oafu.appsync-api.us-east-1.amazonaws.com/graphql

TheApiId is the Id of the AppSync API we just created, theApiKey is the API key of our AppSync API andApiUrl is the AppSync API URL.

Let’s test our endpoint with theSST Console. The SST Console is a web based dashboard to manage your SST apps.Learn more about it in our docs.

Go to theGraphQL tab and you should see the GraphQL Playground in action.

Note, The GraphQL explorer lets you query GraphQL endpoints created with the GraphQLApi and AppSyncApi constructs in your app.

Let’s start by creating a note. Paste the below mutation in the left part of the playground.

mutationcreateNote{createNote(note:{id:"001",content:"My note"}){idcontent}}

GraphQL console create note

Also let’s go to theDynamoDB tab in the SST Console and check that the value has been created in the table.

Note, TheDynamoDB explorer allows you to query the DynamoDB tables in theTable constructs in your app. You can scan the table, query specific keys, create and edit items.

DynamoDB explorer create note

And let’s get the note we just created by running this query instead.

querygetNoteById{getNoteById(noteId:"001"){idcontent}}

GraphQL console get note

Let’s test our update mutation by running:

mutationupdateNote{updateNote(note:{id:"001",content:"My updated note"}){idcontent}}

GraphQL console update note

Now let’s try deleting our note.

mutationdeleteNote{deleteNote(noteId:"001")}

GraphQL console delete note

Let’s test if the delete worked by getting all the notes.

querylistNotes{listNotes{idcontent}}

GraphQL console list notes

You’ll notice a couple of things. Firstly, the note we created is still there. This is because ourdeleteNote method isn’t actually running our query. Secondly, our note should have the updated content from our previous query.

Making changes

Change indicator Let’s fix ourpackages/functions/src/graphql/deleteNote.ts by un-commenting the query.

awaitdynamoDb.delete(params).promise();

If you head back to the query editor and run the delete mutation again.

mutationdeleteNote{deleteNote(noteId:"001")}

GraphQL console delete note after change

And running the list query should now show that the note has been removed!

querylistNotes{listNotes{idcontent}}

GraphQL console list notes after change

Notice we didn’t need to redeploy our app to see the change.

Deploying your API

Now that our API is tested, let’s deploy it to production. You’ll recall that we were using adev environment, the one specified in oursst.config.ts. However, we are going to deploy it to a different environment. This ensures that the next time we are developing locally, it doesn’t break the API for our users.

Change indicator Run the following in your terminal.

$npx sst deploy--stage prod

Cleaning up

Finally, you can remove the resources created in this example using the following commands.

$npx sst remove$npx sst remove--stage prod

Conclusion

And that’s it! You’ve got a brand new serverless GraphQL API built with AppSync. A local development environment, to test and make changes. And it’s deployed to production as well, so you can share it with your users. Check out the repo below for the code we used in this example. And leave a comment if you have any questions!

For help and discussion

Comments on this example

About

SST is an open source framework for building modern full-stack apps.
View on GitHub

[8]ページ先頭

©2009-2025 Movatter.jp