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
    • AI Studio
    • Business tools
  • All Solutions
    • By industry
    • By use case
    • Economics and Pricing
    • Security
    • Technical Support
    • Customer Stories
    • Start testing with double trial credits
    • Cloud credits to scale your IT product
    • Gateway to Russia
    • Cloud for Startups
    • Education and Science
    • Yandex Cloud Partner program
  • Blog
  • Pricing
  • Documentation
© 2025 Direct Cursus Technology L.L.C.
Yandex API Gateway
  • Getting started
    • All tutorials
    • Deploying a web application using the Java Servlet API
    • Creating a skill for Alice and a website with authorization
    • Developing a Slack bot
    • Developing a Telegram bot
    • Developing a Telegram bot for text and audio recognition
    • Developing a custom integration
    • Developing CRUD APIs for movie services
    • Working with an API gateway via WebSocket
    • Creating an interactive serverless application using WebSocket
    • Building a CI/CD pipeline in GitLab with serverless products
    • Interactive debugging of Cloud Functions functions
    • Deploying a web app with JWT authorization in API Gateway and authentication in Firebase
    • Canary release of a Cloud Functions function
    • Using API Gateway to set up speech synthesis in Yandex SpeechKit
    • Running a containerized app in Yandex Serverless Containers
    • URL shortener
    • Entering data into storage systems
    • API Gateway protection with Smart Web Security
  • Access management
  • Pricing policy
  • Terraform reference
  • Monitoring metrics
  • Audit Trails events
  • Release notes
  • FAQ

In this article:

  • Getting started
  • Required paid resources
  • Set up your environment
  • Initiate Terraform
  • Create a Managed Service for YDB database
  • Implement CRUD operations
  • Create a service account
  • Compile the application's TypeScript source code
  • Develop a REST API
  • Deploy your application in Serverless Containers
  • Deploy your API in API Gateway
  • Test the new CRUD API
  • How to delete the resources you created
  1. Tutorials
  2. Developing CRUD APIs for movie services

Developing CRUD APIs for movie services

Written by
Yandex Cloud
Updated at June 3, 2025
  • Getting started
    • Required paid resources
  • Set up your environment
  • Initiate Terraform
  • Create a Managed Service for YDB database
  • Implement CRUD operations
    • Create a service account
    • Compile the application's TypeScript source code
  • Develop a REST API
    • Deploy your application in Serverless Containers
    • Deploy your API in API Gateway
  • Test the new CRUD API
  • How to delete the resources you created

With serverless technology, you can create a CRUD API for a movie data service.

The CRUD API runs inside a container in Yandex Serverless Containers for accessing the movie database deployed in Yandex Managed Service for YDB.

The container is configured in the OpenAPI 3.0-based Yandex API Gateway specification to handle specific HTTP requests.

The container will communicate with Managed Service for YDB and handle external HTTP requests via an API gateway using the Amazon DynamoDB-compatible HTTP API. The CRUD API is written in TypeScript and runs on Node.js 16.

To deploy a project:

  1. Set up your environment.
  2. Initialize Terraform.
  3. Create a Managed Service for YDB database.
  4. Implement CRUD operations.
  5. Develop a REST API.
  6. Test the new 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 container invocation count, computing resources allocated to run the application, and outbound traffic (see Serverless Containers pricing).
  • Fee for the number of requests to the API gateway and outbound traffic (see API Gateway pricing).

Set up your environmentSet up your environment

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

Note

If you are using a distribution other than Ubuntu, install the specified tools using your package manager.

  1. Install the following tools in the specified order by running the relevant commands in your terminal:

    • Curl and Git:

      sudo apt-get install curl git -y
      
    • WebStorm or any other TypeScript-enabled IDE:

      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
      
    • Terraform 1.0.8 or higher:

      sudo apt-get update && sudo apt-get install -y gnupg software-properties-common curl
      curl --fail --silent --show-error --location https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
      sudo apt-add-repository "deb [arch=$(dpkg --print-architecture)] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
      sudo apt-get update && sudo apt-get install terraform -y
      terraform version
      
  2. Create a Yandex Cloud CLI profile with basic settings.

  3. Set up the AWS CLI.

  4. Set up Docker so that a non-root user can manage it:

    sudo groupadd docker
    sudo usermod -aG docker $USER
    newgrp docker
    docker run hello-world
    
  1. Install the following tools in the specified order by running the relevant commands in your 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 TypeScript-enabled IDE:

      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
      
    • Terraform 1.0.8 or higher:

      brew tap hashicorp/tap
      brew install hashicorp/tap/terraform
      terraform version
      
  2. Create a profile with basic settings.

  3. 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 project directory 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 properties:

    yc config profile get <profile_name>
    
  5. Copy these properties 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 Terraform commands in the deploy directory.

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

Our project uses a YDB database in serverless mode. This database consists of two tables: movies to keep movie data and votes to keep user ratings. Each table entry contains the ID and fixed 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 by typing yes in the terminal and pressing Enter.

    You will see these variables in the command output:

    • 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 to environment variables:

    export DOCUMENT_API_ENDPOINT=<DB_Document_API_endpoint>
    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 were successfully 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.

Implement CRUD operationsImplement CRUD operations

Every time you create, read, update, or delete data, the database layer is involved. These actions are collectively called CRUD operations.

In the Document API, you access the database using the AWS SDK for JavaScript v3:

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

All data-related operations use IAM tokens for authorization. Any operation begins by calling the metadata service to get an IAM token.

Create a service accountCreate a service account

  1. The Terraform configuration for creating 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 by typing yes in the terminal and pressing 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 gets the roles for the following purposes:

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

    Make sure to assign the roles for the entire folder rather than an individual resource.

Compile the application's TypeScript source codeCompile the application's TypeScript source code

  1. Go to the repository root directory and install required dependencies with this command:

    cd <path_to_sls-web-application_directory>
    npm ci
    

    After running it, your project will include the node_modules directory with all required dependencies.

  2. Run your project build:

    npm run build
    

    After running it, your project will include the dist directory with the compiled JS files.

Develop a REST APIDevelop a REST API

The openapi/api.yaml file already contains an OpenAPI specification that describes the main operations with movies and ratings.

To implement the service according to the specification, you will use OpenAPI Backend in combination with Express. The app.ts file describes the required classes, operation mappings, and HTTP service initialization.

Deploy your application in Serverless ContainersDeploy your application in Serverless Containers

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

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

  2. The container-registry.tf file defines the configuration of the registry and repository that will store the application Docker image. 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 by typing yes in the terminal and pressing 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. Configure Docker to push images to the created repository:

    yc container registry configure-docker
    
  5. The Dockerfile describes the configuration for building the Docker image. Build the image and push it to the repository:

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

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

    Where:

    • --name: Container name.
    • --folder-id: Folder ID.
  7. The command output gives the new container ID. 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 vCPUs available to 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 application reads the Document API endpoint from the DOCUMENT_API_ENDPOINT environment variable.
    • --service-account-id: Service account ID.
    • --image: Repository name.

Deploy your API in API GatewayDeploy your API in API Gateway

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

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

    terraform apply -target=yandex_api_gateway.movies_api_gateway
    

    Confirm creating the resources by typing yes in the terminal and pressing 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
    

Test the new CRUD APITest the new 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 return an empty list ([]) since there are no entries 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 for 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 the 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 will enable you to easily make REST API calls.

View diagnostic information about the container. In the management console, go to the container page. The Logs tab shows messages about container invocations and the Monitoring tab, charts of container invocations, 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 the resources you created with Terraform, delete them. In the terminal, run this command:

terraform destroy

Confirm the resource deletion by typing yes in the terminal and pressing Enter.

See alsoSee also

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

Was the article helpful?

Previous
Developing a custom integration
Next
Working with an API gateway via WebSocket
© 2025 Direct Cursus Technology L.L.C.