Yandex Cloud
Search
Contact UsGet started
  • Blog
  • Pricing
  • Documentation
  • All Services
  • System Status
    • Featured
    • Infrastructure & Network
    • Data Platform
    • Containers
    • Developer tools
    • Serverless
    • Security
    • Monitoring & Resources
    • ML & AI
    • Business tools
  • All Solutions
    • By industry
    • By use case
    • Economics and Pricing
    • Security
    • Technical Support
    • Customer Stories
    • Gateway to Russia
    • Cloud for Startups
    • Education and Science
  • Blog
  • Pricing
  • Documentation
Yandex project
© 2025 Yandex.Cloud LLC
Tutorials
    • All tutorials
    • URL shortener
    • Entering data into storage systems
    • Storing application runtime logs
    • Deploying a web application using the Java Servlet API
    • Developing a Slack bot
    • Developing a Telegram bot
    • Developing a custom integration in API Gateway
    • Developing CRUD APIs for movie services
    • Building a CI/CD pipeline in GitLab
    • Working with an API gateway via WebSocket
    • Creating an interactive serverless application using WebSocket
    • Automatically copying objects from one Object Storage bucket to another
    • Visualizing logs in Grafana using the Cloud Logging plugin
    • Canary release of a Cloud Functions function
    • Interactive debugging of Cloud Functions functions
    • Creating a Node.js function using TypeScript
    • Running a containerized app in Serverless Containers
    • Streaming Yandex Cloud Postbox events to Data Streams and analyzing them using DataLens
    • Using API Gateway to set up speech synthesis in SpeechKit
    • Connecting to YDB from a Cloud Functions function in Python
    • Connecting to a YDB database from a Cloud Functions function in Node.js
    • API Gateway protection with Smart Web Security
    • Deploying a web app with JWT authorization in API Gateway and authentication in Firebase
    • Automatic data upload to Yandex SpeechSense using Yandex Workflows
    • Configuring responses in Cloud Logging and Yandex Cloud Functions
    • Setting up Workflows integration with Tracker, YandexGPT, and Yandex Cloud Postbox
    • Developing functions in Functions Framework and deploying them to Yandex Serverless Containers

In this article:

  • Getting started
  • Required paid resources
  • Configure the environment
  • Initiate Terraform
  • Create a Managed Service for YDB database
  • Run CRUD operations
  • Create a service account
  • Compile the application source code in TypeScript
  • Develop the REST API
  • Deploy the application in Serverless Containers
  • Deploy the API in API Gateway
  • Check the performance of the created CRUD API
  • How to delete the resources you created
  1. Serverless technologies
  2. Developing CRUD APIs for movie services

Developing CRUD APIs for movie services

Written by
Yandex Cloud
Updated at May 7, 2025
  • Getting started
    • Required paid resources
  • Configure the environment
  • Initiate Terraform
  • Create a Managed Service for YDB database
  • Run CRUD operations
    • Create a service account
    • Compile the application source code in TypeScript
  • Develop the REST API
    • Deploy the application in Serverless Containers
    • Deploy the API in API Gateway
  • Check the performance of the created CRUD API
  • How to delete the resources you created

You can use serverless technology to create a CRUD API for a service that stores movie data.

The CRUD API implementation uses a Yandex Serverless Containers container designed to work with a movie database deployed in Yandex Managed Service for YDB.

The container is configured in the Yandex API Gateway API gateway specifications supporting OpenAPI 3.0 to execute specific HTTP requests.

The container interacts with Managed Service for YDB and processes external HTTP requests via the API gateway using the Amazon DynamoDB-compatible HTTP API. The CRUD API source code language is TypeScript, the runtime environment is Node.js 16.

To deploy a project:

  1. Configure the environment.
  2. Initialize Terraform.
  3. Create a Managed Service for YDB database.
  4. Run CRUD operations.
  5. Develop the REST API.
  6. Check the performance of the CRUD API.

If you no longer need the resources you created, delete them.

Getting startedGetting started

Sign up in Yandex Cloud and create a billing account:

  1. Navigate to the management console and log in to Yandex Cloud or register a new account.
  2. On the Yandex Cloud Billing page, make sure you have a billing account linked and it has the ACTIVE or TRIAL_ACTIVE status. If you do not have a billing account, create one and link a cloud to it.

If you have an active billing account, you can navigate to the cloud page to create or select a folder for your infrastructure to operate in.

Learn more about clouds and folders.

Required paid resourcesRequired paid resources

The cost of CRUD API resources includes:

  • Fee for YDB operations and data storage (see Managed Service for YDB pricing for serverless mode).
  • Fee for the number of container calls, computing resources allocated to execute the application, and outgoing traffic (see Serverless Containers pricing).
  • Fee for the number of requests to the API gateway and outgoing traffic (see API Gateway pricing).

Configure the environmentConfigure the environment

Windows
Linux
macOS
  1. Install the WSL utility to run a Linux environment.
  2. Run the Linux subsystem (by default, Ubuntu).
  3. Configure the environment as described in the Linux manual.

Note

If you use a distribution other than Ubuntu, install the specified utilities using your package manager commands.

  1. Install the following utilities in the specified order using commands in the terminal:

    • Curl and Git:

      sudo apt-get install curl git -y
      
    • WebStorm or any other development environment that supports TypeScript:

      sudo snap install webstorm --classic
      
    • Node.js 16.9.1 or higher:

      curl --silent --location https://deb.nodesource.com/setup_16.x | sudo -E bash
      sudo apt-get install nodejs
      node -v
      npm -v
      
    • TypeScript:

      sudo npm install -g typescript
      
    • Yandex Cloud CLI:

      curl https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash
      exec -l $SHELL
      yc version
      
    • AWS CLI:

      curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" --output "awscliv2.zip"
      unzip awscliv2.zip
      sudo ./aws/install
      
    • Docker:

      sudo apt-get update
      sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release -y
      curl --fail --silent --show-error --location https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
      echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
      sudo apt-get update
      sudo apt-get install docker-ce docker-ce-cli containerd.io -y
      sudo docker run hello-world
      
  2. Install Terraform 1.0.8 or higher.

  3. Create a Yandex Cloud CLI profile with basic parameters.

  4. Set up the AWS CLI.

  5. Set up Docker management on behalf of a user without privileges.

    sudo groupadd docker
    sudo usermod -aG docker $USER
    newgrp docker
    docker run hello-world
    
  1. Install the following utilities in the specified order using commands in the terminal:

    • Homebrew:

      /bin/bash -c "$(curl --fail --silent --show-error --location https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
      
    • Curl and Git:

      brew install curl git
      
    • WebStorm or any other development environment that supports TypeScript:

      brew install --cask webstorm
      
    • Node.js 16.9.1 or higher:

      brew install node
      node -v
      npm -v
      
    • TypeScript:

      npm install -g typescript
      
    • Yandex Cloud CLI:

      curl https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash
      exec -l $SHELL
      yc version
      
    • AWS CLI:

      curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" --output "AWSCLIV2.pkg"
      sudo installer -pkg AWSCLIV2.pkg -target /
      
    • Docker:

      brew install --cask docker
      
  2. Install Terraform 1.0.8 or higher.

  3. Create a profile with basic parameters.

  4. Set up the AWS CLI.

Initiate TerraformInitiate Terraform

  1. Clone a repository with source files for the CRUD API project:

    git clone https://github.com/yandex-cloud-examples/yc-practicum-serverless-web-application-movie-website.git
    

    Open the folder project in WebStorm and review the source files.

  2. Go to the deploy directory:

    cd <path_to_deploy_directory>
    
  3. Find out the name of the ACTIVE profile of the Yandex Cloud CLI. In the terminal, run this command:

    yc config profile list
    
  4. Get the active profile parameters:

    yc config profile get <profile_name>
    
  5. Copy the parameters to provider.tf:

    • token: OAuth token.
    • cloud-id: Cloud ID.
    • folder-id: Folder ID.
  6. Export the folder ID to the environment variable:

    export FOLDER_ID=<folder_ID>
    echo $FOLDER_ID
    
  7. Run the Terraform initialization command:

    terraform init
    

    Note

    Run all the Terraform commands in the deploy folder.

Create a Managed Service for YDB databaseCreate a Managed Service for YDB database

The project uses a YDB database in serverless mode. The database consists of two tables: movies to keep movie data and votes to keep user ratings. Each table entry contains the ID and the final set of attributes.

  1. The Terraform configuration for database creation is described in ydb.tf. Create a database:

    terraform apply -target=yandex_ydb_database_serverless.movies_database
    

    Confirm creating the resources: type yes in the terminal and press Enter.

    The command result contains the variables:

    • movies_database_document_api_endpoint: Document API endpoint of the database.
    • movies_database_path: Relative path to the database.

    Use the management console or the yc ydb database list CLI command to check that the movies-database DB has been successfully created.

  2. Export the movies_database_document_api_endpoint and movies_database_path values from the previous command output into environment variables:

    export DOCUMENT_API_ENDPOINT=<Document_API_endpoint_of_DB>
    echo $DOCUMENT_API_ENDPOINT
    
    export MOVIES_DATABASE_PATH=<relative_path_to_database>
    echo $MOVIES_DATABASE_PATH
    
  3. Create tables named movies and votes in movies-database:

    aws dynamodb create-table \
      --table-name movies \
      --attribute-definitions \
        AttributeName=id,AttributeType=N \
        AttributeName=title,AttributeType=S \
        AttributeName=type,AttributeType=S \
        AttributeName=original_title,AttributeType=S \
        AttributeName=original_language,AttributeType=S \
        AttributeName=release_date,AttributeType=S \
        AttributeName=poster_path,AttributeType=S \
        AttributeName=popularity,AttributeType=N \
        AttributeName=video,AttributeType=S \
        AttributeName=vote_count,AttributeType=N \
        AttributeName=vote_average,AttributeType=N \
        AttributeName=genres,AttributeType=S \
        AttributeName=backdrop_path,AttributeType=S \
        AttributeName=adult,AttributeType=S \
        AttributeName=overview,AttributeType=S \
      --key-schema \
        AttributeName=id,KeyType=HASH \
      --global-secondary-indexes \
        "[
          {
            \"IndexName\": \"PopularityIndex\",
            \"KeySchema\": [{\"AttributeName\":\"type\",\"KeyType\":\"HASH\"}, {\"AttributeName\":\"popularity\",\"KeyType\":\"RANGE\"}],
            \"Projection\":{
              \"ProjectionType\":\"ALL\"
            }
          }
        ]" \
      --endpoint ${DOCUMENT_API_ENDPOINT}
    
    aws dynamodb create-table \
      --table-name votes \
      --attribute-definitions \
        AttributeName=id,AttributeType=S \
        AttributeName=user_id,AttributeType=S \
        AttributeName=movie_id,AttributeType=N \
        AttributeName=value,AttributeType=N \
      --key-schema \
        AttributeName=id,KeyType=HASH \
      --global-secondary-indexes \
        "[
          {
            \"IndexName\": \"MovieIndex\",
            \"KeySchema\": [{\"AttributeName\":\"movie_id\",\"KeyType\":\"HASH\"}],
            \"Projection\":{
              \"ProjectionType\":\"ALL\"
            }
          }
        ]" \
      --endpoint ${DOCUMENT_API_ENDPOINT}
    
  4. Make sure the tables are created:

    aws dynamodb describe-table \
      --table-name movies \
      --endpoint ${DOCUMENT_API_ENDPOINT}
    
    aws dynamodb describe-table \
      --table-name votes \
      --endpoint ${DOCUMENT_API_ENDPOINT}
    

    Each table supports two indexes:

    • The movies table supports an index to quickly find a movie by its ID and an index to sort movies by popularity.
    • The votes table supports an index to locate a user's rating for a movie and an index to get all ratings for a movie.

Run CRUD operationsRun CRUD operations

A database layer is used every time data is retrieved, updated, or deleted. These actions are called CRUD operations.

In the Document API, you interact with the database with the help of the AWS SDK for JavaScript v3 library:

  • model.ts defines the Movie and Vote models via the TypeScript interface.
  • repository.ws implements CRUD operations for using these entities.

IAM tokens are used for authorization when data operations are executed. To get an IAM token before the operation, the metadata service is called.

Create a service accountCreate a service account

  1. The Terraform configuration to create a service account is described in sa.tf. Create a service account:

    terraform apply -target=yandex_iam_service_account.movies_api_sa
    

    Confirm creating the resources: type yes in the terminal and press Enter.

  2. In the command output, the movies_api_sa_id variable contains the ID of the new service account. Export it to the environment variable:

    export MOVIES_API_SA_ID=<service_account_ID>
    echo $MOVIES_API_SA_ID
    
  3. Assign roles to the service account:

    yc resource-manager folder add-access-binding ${FOLDER_ID} \
      --role ydb.admin \
      --subject serviceAccount:${MOVIES_API_SA_ID}
    
    yc resource-manager folder add-access-binding ${FOLDER_ID} \
      --role container-registry.images.puller \
      --subject serviceAccount:${MOVIES_API_SA_ID}
    
    yc resource-manager folder add-access-binding ${FOLDER_ID} \
      --role serverless.containers.invoker \
      --subject serviceAccount:${MOVIES_API_SA_ID}
    

    Where:

    • --role: Role you want to assign.
    • --subject serviceAccount: Service account ID.

    The service account is assigned roles for the following actions:

    • Invoking a container in Serverless Containers.
    • Running operations in YDB.

    The roles are assigned to the whole folder rather than an individual resource.

Compile the application source code in TypeScriptCompile the application source code in TypeScript

  1. Go to the repository root folder and install all the necessary dependencies:

    cd <path_to_sls-web-application_directory>
    npm ci
    

    After the command is executed, the node_modules directory with all the required dependencies will appear in the project.

  2. Run the project build:

    npm run build
    

    After the command is executed, the dist directory with the compiled JS files will appear in the project.

Develop the REST APIDevelop the REST API

The openapi/api.yaml file already has the OpenAPI specifications, which describe the main operations with movies and rates.

To implement the service according to the specifications, the OpenAPI Backend library is used in combination with the Express framework. The app.ts file describes required classes, operation mapping, and the launch of an HTTP service.

Deploy the application in Serverless ContainersDeploy the application in Serverless Containers

Build the application as a Docker image and run it in Serverless Containers:

  1. In the OpenAPI specifications (api.yaml), type the ID of the previously created service account in the x-yc-apigateway.service_account_id field.

  2. The container-registry.tf file describes a configuration of the registry and repository to which an application Docker image will be pushed. Go to the deploy directory and create resources in Yandex Container Registry:

    cd <path_to_deploy_directory>
    terraform apply -target=yandex_container_registry.default
    terraform apply -target=yandex_container_repository.movies_api_repository
    

    Confirm creating the resources: type yes in the terminal and press Enter.

  3. In the command output, the movies_api_repository_name variable contains the name of the repository to upload the Docker image to. Export it to the environment variable:

    export MOVIES_API_REPOSITORY_NAME=<repository_name>
    echo $MOVIES_API_REPOSITORY_NAME
    
  4. Set up Docker for the created repository:

    yc container registry configure-docker
    
  5. The Dockerfile describes a configuration to build a Docker image. Build the image and push it to the repository created in the previous step:

    docker build -t ${MOVIES_API_REPOSITORY_NAME}:0.0.1 .
    docker push ${MOVIES_API_REPOSITORY_NAME}:0.0.1
    
  6. Create a Serverless Containers container:

    yc sls container create \
      --name movies-api-container \
      --folder-id ${FOLDER_ID}
    

    Where:

    • --name: Container name.
    • --folder-id: Folder ID.
  7. The command result shows the ID of the container. Export it to the environment variable:

    export MOVIES_API_CONTAINER_ID=<container_ID>
    echo $MOVIES_API_CONTAINER_ID
    
  8. Create a container revision from Docker image 0.0.1:

    yc sls container revisions deploy \
      --folder-id ${FOLDER_ID} \
      --container-id ${MOVIES_API_CONTAINER_ID} \
      --memory 512M \
      --cores 1 \
      --execution-timeout 5s \
      --concurrency 4 \
      --environment AWS_ACCESS_KEY_ID=FAKE_AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY=FAKE_AWS_SECRET_ACCESS_KEY,DOCUMENT_API_ENDPOINT=${DOCUMENT_API_ENDPOINT} \
      --service-account-id ${MOVIES_API_SA_ID} \
      --image ${MOVIES_API_REPOSITORY_NAME}:0.0.1
    

    Where:

    • --folder-id: Folder ID.
    • --container-id: Container ID.
    • --memory: Memory available for the container.
    • --cores: Number of vCPU cores available for the container.
    • --execution-timeout: Execution timeout.
    • --concurrency: Maximum number of concurrent container invocations. If the number of container invocations exceeds the --concurrency value, Serverless Containers scales the container up by running its additional instances.
    • --environment: Environment variables. The Document API endpoint of a database is communicated to the application via the DOCUMENT_API_ENDPOINT environment variable.
    • --service-account-id: Service account ID.
    • --image: Repository name.

Deploy the API in API GatewayDeploy the API in API Gateway

  1. In the OpenAPI specifications (api.yaml), replace the ${MOVIES_API_CONTAINER_ID} variable with the ID of the container you created.

  2. The api-gateway.tf file describes a Terraform configuration for creating the API gateway. Deploy the API gateway:

    terraform apply -target=yandex_api_gateway.movies_api_gateway
    

    Confirm creating the resources: type yes in the terminal and press Enter.

  3. In the command output, the movies_api_gateway_domain variable contains the domain name of the API gateway. Export it to the environment variable:

    export MOVIES_API_GATEWAY_DOMAIN=<API_gateway_domain_name>
    echo $MOVIES_API_GATEWAY_DOMAIN
    

Check the performance of the created CRUD APICheck the performance of the created CRUD API

To test the new CRUD API, run the following HTTP requests using the curl command:

  1. Retrieve a movie list:

    curl "${MOVIES_API_GATEWAY_DOMAIN}/movies?limit=10"
    

    The response must contain an empty list ([]) as there is no data in the database yet.

  2. Add movie details:

    curl \
      --location \
      --request POST 'https://${MOVIES_API_GATEWAY_DOMAIN}/movies' \
      --header 'Content-Type: application/json' \
      --data-raw '{
        "id": "301",
        "title": "The Matrix",
        "release_date": 1999
      }'
    
  3. Retrieve movie details:

    curl \
      --location \
      --request GET 'https://${MOVIES_API_GATEWAY_DOMAIN}/movies/301'
    
  4. Add details of another movie:

    curl \
      --location \
      --request POST 'https://${MOVIES_API_GATEWAY_DOMAIN}/movies' \
      --header 'Content-Type: application/json' \
      --data-raw '{
        "id": "299",
        "title": "The Matrix Reloaded",
        "release_date": 2003
      }'
    
  5. Retrieve a movie list:

    curl \
      --location \
      --request GET 'https://${MOVIES_API_GATEWAY_DOMAIN}/movies?from=1&limit=5'
    

You can also upload a specification to Postman or SwaggerHub by adding the address of the created API gateway from the ${MOVIES_API_GATEWAY_DOMAIN} variable to the servers section. This enables you to easily run requests to the REST API.

View diagnostic information about the container. In the management console, go to the container page. The Logs tab shows messages about container calls and the Monitoring tab charts of container calls, average request processing times, and number of errors.

You can also view monitoring logs and charts on the API gateway page.

How to delete the resources you createdHow to delete the resources you created

To stop paying for resources created using Terraform, delete them. In the terminal, run this command:

terraform destroy

Confirm the resource deletion: type yes in the terminal and press Enter.

See alsoSee also

  • Getting started with Terraform.
  • Terraform reference. Yandex Cloud provider.
  • Document table.
  • X-yc-apigateway-integration extension.
  • Container logs.
  • Viewing container monitoring charts.

Was the article helpful?

Previous
Developing a custom integration in API Gateway
Next
Building a CI/CD pipeline in GitLab
Yandex project
© 2025 Yandex.Cloud LLC