Эҷоди CRUD зуд бо nest, @nestjsx/crud ва TestMace

Эҷоди CRUD зуд бо nest, @nestjsx/crud ва TestMace

Дар айни замон, REST API ба стандарти таҳияи барномаҳои веб табдил ёфтааст, ки имкон медиҳад таҳия ба қисмҳои мустақил тақсим карда шавад. Дар айни замон барои UI чаҳорчӯбаҳои гуногуни маъмул, аз қабили Angular, React, Vue ва дигарон истифода мешаванд. Таҳиягарони пуштибонида метавонанд аз доираи васеи забонҳо ва чаҳорчӯбаҳо интихоб кунанд. Имруз ман мехостам дар бораи чунин чорчуба сухан ронам, монанди NestJS. Мо дар TestMace Мо онро барои лоиҳаҳои дохилӣ фаъолона истифода мебарем. Истифодаи лона ва баста @nestjsx/crud, мо як барномаи оддии CRUD эҷод мекунем.

Чаро NestJS

Ба наздикӣ, дар ҷомеаи JavaScript бисёр чаҳорчӯбаҳои пуштибонӣ пайдо шуданд. Ва агар аз ҷиҳати функсионалӣ онҳо ба Nest қобилиятҳои шабеҳро пешниҳод кунанд, пас дар як чиз он бешубҳа ғолиб меояд - ин меъморӣ аст. Хусусиятҳои зерини NestJS ба шумо имкон медиҳанд, ки замимаҳои саноатӣ эҷод кунед ва миқёси таҳияи дастаҳои калонро эҷод кунед:

  • истифодаи TypeScript ҳамчун забони асосии рушд. Гарчанде ки NestJS JavaScript-ро дастгирӣ мекунад, баъзе функсияҳо метавонанд кор накунанд, хусусан агар сухан дар бораи бастаҳои тарафи сеюм бошад;
  • мавҷудияти контейнери DI, ки ба шумо имкон медиҳад, ки ҷузъҳои ба ҳам пайвастшуда эҷод кунед;
  • Функсияи худи чаҳорчӯба ба ҷузъҳои мустақили ивазшаванда тақсим карда мешавад. Масалан, дар зери кулоҳ ҳамчун чаҳорчӯбаи он метавонад ҳамчун истифода шавад баён, ва тезондан, барои кор бо базаи маълумот, лона берун аз қуттии таъмин пайвандҳо ба тип, манғус, давом додан;
  • NestJS платформаи агностикӣ буда, REST, GraphQL, Websockets, gRPC ва ғайраро дастгирӣ мекунад.

Худи чаҳорчӯба аз чаҳорчӯбаи frontend Angular илҳом гирифта шудааст ва аз ҷиҳати консептуалӣ бо он умумияти зиёд дорад.

Насб кардани NestJS ва ҷойгиркунии лоиҳа

Nest дорои баста аст лона/cli, ки ба шумо имкон медиҳад, ки чаҳорчӯбаи асосии барномаро зуд ҷойгир кунед. Биёед ин бастаро дар саросари ҷаҳон насб кунем:

npm install --global @nest/cli

Пас аз насб, мо чаҳорчӯбаи асосии замимаи худро бо ном тавлид мекунем лона-рест. Ин бо истифода аз фармон анҷом дода мешавад nest new nest-rest.

лона лона- истирохати нав

dmitrii@dmitrii-HP-ZBook-17-G3:~/projects $ nest new nest-rest
  We will scaffold your app in a few seconds..

CREATE /nest-rest/.prettierrc (51 bytes)
CREATE /nest-rest/README.md (3370 bytes)
CREATE /nest-rest/nest-cli.json (84 bytes)
CREATE /nest-rest/nodemon-debug.json (163 bytes)
CREATE /nest-rest/nodemon.json (67 bytes)
CREATE /nest-rest/package.json (1805 bytes)
CREATE /nest-rest/tsconfig.build.json (97 bytes)
CREATE /nest-rest/tsconfig.json (325 bytes)
CREATE /nest-rest/tslint.json (426 bytes)
CREATE /nest-rest/src/app.controller.spec.ts (617 bytes)
CREATE /nest-rest/src/app.controller.ts (274 bytes)
CREATE /nest-rest/src/app.module.ts (249 bytes)
CREATE /nest-rest/src/app.service.ts (142 bytes)
CREATE /nest-rest/src/main.ts (208 bytes)
CREATE /nest-rest/test/app.e2e-spec.ts (561 bytes)
CREATE /nest-rest/test/jest-e2e.json (183 bytes)

? Which package manager would you ️ to use? yarn
 Installation in progress... 

  Successfully created project nest-rest
  Get started with the following commands:

$ cd nest-rest
$ yarn run start

                          Thanks for installing Nest 
                 Please consider donating to our open collective
                        to help us maintain this package.

                 Donate: https://opencollective.com/nest

Мо калобаро ҳамчун мудири бастаи худ интихоб мекунем.
Дар ин лаҳза шумо метавонед серверро бо фармон оғоз кунед npm start ва ба суроға меравед http://localhost:3000 шумо метавонед саҳифаи асосиро бинед. Вале аз ин сабаб нест, ки мо дар ин ҷо ҷамъ омадаем ва мо пеш рафта истодаем.

Ташкили кор бо базаи маълумот

Ман PostrgreSQL-ро ҳамчун DBMS барои ин мақола интихоб кардам. Дар бораи завқ баҳс нест; ба назари ман, ин DBMS баркамолтарин аст, ки дорои тамоми қобилиятҳои зарурӣ мебошад. Тавре ки аллакай зикр гардид, Nest ҳамгироиро бо бастаҳои гуногун барои кор бо пойгоҳи додаҳо таъмин мекунад. Зеро Азбаски интихоби ман ба PostgreSQL афтод, интихоби TypeORM ҳамчун ORM мантиқӣ мебуд. Биёед бастаҳои заруриро барои ҳамгироӣ бо пойгоҳи додаҳо насб кунем:

yarn add typeorm @nestjs/typeorm pg

Барои ҳар як баста барои чӣ лозим аст:

  1. typeorm - бастаи бевосита аз худи ORM;
  2. @nestjs/typeorm - Бастаи TypeORM барои NestJS. Модулҳоро барои воридот ба модулҳои лоиҳа, инчунин маҷмӯи ороишгарони ёрирасон илова мекунад;
  3. pg - драйвер барои кор бо PostgreSQL.

Хуб, бастаҳо насб карда шуданд, акнун шумо бояд худи пойгоҳи додаҳоро оғоз кунед. Барои ҷойгиркунии пойгоҳи додаҳо, ман docker-compose.yml-ро бо мундариҷаи зерин истифода хоҳам кард:

Доктор-compose.yml

version: '3.1'

services:
  db:
    image: postgres:11.2
    restart: always
    environment:
      POSTGRES_PASSWORD: example
    volumes:
      - ../db:/var/lib/postgresql/data
      - ./postgresql.conf:/etc/postgresql/postgresql.conf
    ports:
      - 5432:5432
  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

Тавре ки шумо мебинед, ин файл оғози 2 контейнерро танзим мекунад:

  1. db як контейнерест, ки бевосита пойгоҳи додаҳоро дар бар мегирад. Дар ҳолати мо, версияи postgresql 11.2 истифода мешавад;
  2. админ — мудири махзани маълумот. Интерфейси вебро барои дидан ва идоракунии пойгоҳи додаҳо таъмин мекунад.

Барои кор бо пайвастҳои tcp, ман конфигуратсияи зеринро илова кардам.

postgresql.conf

# -----------------------------
# PostgreSQL configuration file
# -----------------------------
#
# This file consists of lines of the form:
#
#   name = value
#
# (The "=" is optional.)  Whitespace may be used.  Comments are introduced with
# "#" anywhere on a line.  The complete list of parameter names and allowed
# values can be found in the PostgreSQL documentation.
#
# The commented-out settings shown in this file represent the default values.
# Re-commenting a setting is NOT sufficient to revert it to the default value;
# you need to reload the server.
#
# This file is read on server startup and when the server receives a SIGHUP
# signal.  If you edit the file on a running system, you have to SIGHUP the
# server for the changes to take effect, run "pg_ctl reload", or execute
# "SELECT pg_reload_conf()".  Some parameters, which are marked below,
# require a server shutdown and restart to take effect.
#
# Any parameter can also be given as a command-line option to the server, e.g.,
# "postgres -c log_connections=on".  Some parameters can be changed at run time
# with the "SET" SQL command.
#
# Memory units:  kB = kilobytes        Time units:  ms  = milliseconds
#                MB = megabytes                     s   = seconds
#                GB = gigabytes                     min = minutes
#                TB = terabytes                     h   = hours
#                                                   d   = days
#------------------------------------------------------------------------------
# FILE LOCATIONS
#------------------------------------------------------------------------------
# The default values of these variables are driven from the -D command-line
# option or PGDATA environment variable, represented here as ConfigDir.
#data_directory = 'ConfigDir'       # use data in another directory
# (change requires restart)
#hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file
# (change requires restart)
#ident_file = 'ConfigDir/pg_ident.conf' # ident configuration file
# (change requires restart)
# If external_pid_file is not explicitly set, no extra PID file is written.
#external_pid_file = ''         # write an extra PID file
# (change requires restart)
#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------
# - Connection Settings -
listen_addresses = '*'
#listen_addresses = 'localhost'     # what IP address(es) to listen on;
# comma-separated list of addresses;
# defaults to 'localhost'; use '*' for all
# (change requires restart)
#port = 5432                # (change requires restart)
#max_connections = 100          # (change requires restart)
#superuser_reserved_connections = 3 # (change requires restart)
#unix_socket_directories = '/tmp'   # comma-separated list of directories
# (change requires restart)
#unix_socket_group = ''         # (change requires restart)
#unix_socket_permissions = 0777     # begin with 0 to use octal notation
# (change requires restart)
#bonjour = off              # advertise server via Bonjour
# (change requires restart)
#bonjour_name = ''          # defaults to the computer name
# (change requires restart)
# - TCP Keepalives -
# see "man 7 tcp" for details
#tcp_keepalives_idle = 0        # TCP_KEEPIDLE, in seconds;
# 0 selects the system default
#tcp_keepalives_interval = 0        # TCP_KEEPINTVL, in seconds;
# 0 selects the system default
#tcp_keepalives_count = 0       # TCP_KEEPCNT;
# 0 selects the system default
# - Authentication -
#authentication_timeout = 1min      # 1s-600s
#password_encryption = md5      # md5 or scram-sha-256
#db_user_namespace = off
# GSSAPI using Kerberos
#krb_server_keyfile = ''
#krb_caseins_users = off
# - SSL -
#ssl = off
#ssl_ca_file = ''
#ssl_cert_file = 'server.crt'
#ssl_crl_file = ''
#ssl_key_file = 'server.key'
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
#ssl_prefer_server_ciphers = on
#ssl_ecdh_curve = 'prime256v1'
#ssl_min_protocol_version = 'TLSv1'
#ssl_max_protocol_version = ''
#ssl_dh_params_file = ''
#ssl_passphrase_command = ''
#ssl_passphrase_command_supports_reload = off
#------------------------------------------------------------------------------
# RESOURCE USAGE (except WAL)
#------------------------------------------------------------------------------
# - Memory -
#shared_buffers = 32MB          # min 128kB
# (change requires restart)
#huge_pages = try           # on, off, or try
# (change requires restart)
#temp_buffers = 8MB         # min 800kB
#max_prepared_transactions = 0      # zero disables the feature
# (change requires restart)
# Caution: it is not advisable to set max_prepared_transactions nonzero unless
# you actively intend to use prepared transactions.
#work_mem = 4MB             # min 64kB
#maintenance_work_mem = 64MB        # min 1MB
#autovacuum_work_mem = -1       # min 1MB, or -1 to use maintenance_work_mem
#max_stack_depth = 2MB          # min 100kB
#shared_memory_type = mmap      # the default is the first option
# supported by the operating system:
#   mmap
#   sysv
#   windows
# (change requires restart)
#dynamic_shared_memory_type = posix # the default is the first option
# supported by the operating system:
#   posix
#   sysv
#   windows
#   mmap
# (change requires restart)
# - Disk -
#temp_file_limit = -1           # limits per-process temp file space
# in kB, or -1 for no limit
# - Kernel Resources -
#max_files_per_process = 1000       # min 25
# (change requires restart)
# - Cost-Based Vacuum Delay -
#vacuum_cost_delay = 0          # 0-100 milliseconds (0 disables)
#vacuum_cost_page_hit = 1       # 0-10000 credits
#vacuum_cost_page_miss = 10     # 0-10000 credits
#vacuum_cost_page_dirty = 20        # 0-10000 credits
#vacuum_cost_limit = 200        # 1-10000 credits
# - Background Writer -
#bgwriter_delay = 200ms         # 10-10000ms between rounds
#bgwriter_lru_maxpages = 100        # max buffers written/round, 0 disables
#bgwriter_lru_multiplier = 2.0      # 0-10.0 multiplier on buffers scanned/round
#bgwriter_flush_after = 0       # measured in pages, 0 disables
# - Asynchronous Behavior -
#effective_io_concurrency = 1       # 1-1000; 0 disables prefetching
#max_worker_processes = 8       # (change requires restart)
#max_parallel_maintenance_workers = 2   # taken from max_parallel_workers
#max_parallel_workers_per_gather = 2    # taken from max_parallel_workers
#parallel_leader_participation = on
#max_parallel_workers = 8       # maximum number of max_worker_processes that
# can be used in parallel operations
#old_snapshot_threshold = -1        # 1min-60d; -1 disables; 0 is immediate
# (change requires restart)
#backend_flush_after = 0        # measured in pages, 0 disables
#------------------------------------------------------------------------------
# WRITE-AHEAD LOG
#------------------------------------------------------------------------------
# - Settings -
#wal_level = replica            # minimal, replica, or logical
# (change requires restart)
#fsync = on             # flush data to disk for crash safety
# (turning this off can cause
# unrecoverable data corruption)
#synchronous_commit = on        # synchronization level;
# off, local, remote_write, remote_apply, or on
#wal_sync_method = fsync        # the default is the first option
# supported by the operating system:
#   open_datasync
#   fdatasync (default on Linux)
#   fsync
#   fsync_writethrough
#   open_sync
#full_page_writes = on          # recover from partial page writes
#wal_compression = off          # enable compression of full-page writes
#wal_log_hints = off            # also do full page writes of non-critical updates
# (change requires restart)
#wal_buffers = -1           # min 32kB, -1 sets based on shared_buffers
# (change requires restart)
#wal_writer_delay = 200ms       # 1-10000 milliseconds
#wal_writer_flush_after = 1MB       # measured in pages, 0 disables
#commit_delay = 0           # range 0-100000, in microseconds
#commit_siblings = 5            # range 1-1000
# - Checkpoints -
#checkpoint_timeout = 5min      # range 30s-1d
#max_wal_size = 1GB
#min_wal_size = 80MB
#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0
#checkpoint_flush_after = 0     # measured in pages, 0 disables
#checkpoint_warning = 30s       # 0 disables
# - Archiving -
#archive_mode = off     # enables archiving; off, on, or always
# (change requires restart)
#archive_command = ''       # command to use to archive a logfile segment
# placeholders: %p = path of file to archive
#               %f = file name only
# e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'
#archive_timeout = 0        # force a logfile segment switch after this
# number of seconds; 0 disables
# - Archive Recovery -
# These are only used in recovery mode.
#restore_command = ''       # command to use to restore an archived logfile segment
# placeholders: %p = path of file to restore
#               %f = file name only
# e.g. 'cp /mnt/server/archivedir/%f %p'
# (change requires restart)
#archive_cleanup_command = ''   # command to execute at every restartpoint
#recovery_end_command = ''  # command to execute at completion of recovery
# - Recovery Target -
# Set these only when performing a targeted recovery.
#recovery_target = ''       # 'immediate' to end recovery as soon as a
# consistent state is reached
# (change requires restart)
#recovery_target_name = ''  # the named restore point to which recovery will proceed
# (change requires restart)
#recovery_target_time = ''  # the time stamp up to which recovery will proceed
# (change requires restart)
#recovery_target_xid = ''   # the transaction ID up to which recovery will proceed
# (change requires restart)
#recovery_target_lsn = ''   # the WAL LSN up to which recovery will proceed
# (change requires restart)
#recovery_target_inclusive = on # Specifies whether to stop:
# just after the specified recovery target (on)
# just before the recovery target (off)
# (change requires restart)
#recovery_target_timeline = 'latest'    # 'current', 'latest', or timeline ID
# (change requires restart)
#recovery_target_action = 'pause'   # 'pause', 'promote', 'shutdown'
# (change requires restart)
#------------------------------------------------------------------------------
# REPLICATION
#------------------------------------------------------------------------------
# - Sending Servers -
# Set these on the master and on any standby that will send replication data.
#max_wal_senders = 10       # max number of walsender processes
# (change requires restart)
#wal_keep_segments = 0      # in logfile segments; 0 disables
#wal_sender_timeout = 60s   # in milliseconds; 0 disables
#max_replication_slots = 10 # max number of replication slots
# (change requires restart)
#track_commit_timestamp = off   # collect timestamp of transaction commit
# (change requires restart)
# - Master Server -
# These settings are ignored on a standby server.
#synchronous_standby_names = '' # standby servers that provide sync rep
# method to choose sync standbys, number of sync standbys,
# and comma-separated list of application_name
# from standby(s); '*' = all
#vacuum_defer_cleanup_age = 0   # number of xacts by which cleanup is delayed
# - Standby Servers -
# These settings are ignored on a master server.
#primary_conninfo = ''          # connection string to sending server
# (change requires restart)
#primary_slot_name = ''         # replication slot on sending server
# (change requires restart)
#promote_trigger_file = ''      # file name whose presence ends recovery
#hot_standby = on           # "off" disallows queries during recovery
# (change requires restart)
#max_standby_archive_delay = 30s    # max delay before canceling queries
# when reading WAL from archive;
# -1 allows indefinite delay
#max_standby_streaming_delay = 30s  # max delay before canceling queries
# when reading streaming WAL;
# -1 allows indefinite delay
#wal_receiver_status_interval = 10s # send replies at least this often
# 0 disables
#hot_standby_feedback = off     # send info from standby to prevent
# query conflicts
#wal_receiver_timeout = 60s     # time that receiver waits for
# communication from master
# in milliseconds; 0 disables
#wal_retrieve_retry_interval = 5s   # time to wait before retrying to
# retrieve WAL after a failed attempt
#recovery_min_apply_delay = 0       # minimum delay for applying changes during recovery
# - Subscribers -
# These settings are ignored on a publisher.
#max_logical_replication_workers = 4    # taken from max_worker_processes
# (change requires restart)
#max_sync_workers_per_subscription = 2  # taken from max_logical_replication_workers
#------------------------------------------------------------------------------
# QUERY TUNING
#------------------------------------------------------------------------------
# - Planner Method Configuration -
#enable_bitmapscan = on
#enable_hashagg = on
#enable_hashjoin = on
#enable_indexscan = on
#enable_indexonlyscan = on
#enable_material = on
#enable_mergejoin = on
#enable_nestloop = on
#enable_parallel_append = on
#enable_seqscan = on
#enable_sort = on
#enable_tidscan = on
#enable_partitionwise_join = off
#enable_partitionwise_aggregate = off
#enable_parallel_hash = on
#enable_partition_pruning = on
# - Planner Cost Constants -
#seq_page_cost = 1.0            # measured on an arbitrary scale
#random_page_cost = 4.0         # same scale as above
#cpu_tuple_cost = 0.01          # same scale as above
#cpu_index_tuple_cost = 0.005       # same scale as above
#cpu_operator_cost = 0.0025     # same scale as above
#parallel_tuple_cost = 0.1      # same scale as above
#parallel_setup_cost = 1000.0   # same scale as above
#jit_above_cost = 100000        # perform JIT compilation if available
# and query more expensive than this;
# -1 disables
#jit_inline_above_cost = 500000     # inline small functions if query is
# more expensive than this; -1 disables
#jit_optimize_above_cost = 500000   # use expensive JIT optimizations if
# query is more expensive than this;
# -1 disables
#min_parallel_table_scan_size = 8MB
#min_parallel_index_scan_size = 512kB
#effective_cache_size = 4GB
# - Genetic Query Optimizer -
#geqo = on
#geqo_threshold = 12
#geqo_effort = 5            # range 1-10
#geqo_pool_size = 0         # selects default based on effort
#geqo_generations = 0           # selects default based on effort
#geqo_selection_bias = 2.0      # range 1.5-2.0
#geqo_seed = 0.0            # range 0.0-1.0
# - Other Planner Options -
#default_statistics_target = 100    # range 1-10000
#constraint_exclusion = partition   # on, off, or partition
#cursor_tuple_fraction = 0.1        # range 0.0-1.0
#from_collapse_limit = 8
#join_collapse_limit = 8        # 1 disables collapsing of explicit
# JOIN clauses
#force_parallel_mode = off
#jit = on               # allow JIT compilation
#plan_cache_mode = auto         # auto, force_generic_plan or
# force_custom_plan
#------------------------------------------------------------------------------
# REPORTING AND LOGGING
#------------------------------------------------------------------------------
# - Where to Log -
#log_destination = 'stderr'     # Valid values are combinations of
# stderr, csvlog, syslog, and eventlog,
# depending on platform.  csvlog
# requires logging_collector to be on.
# This is used when logging to stderr:
#logging_collector = off        # Enable capturing of stderr and csvlog
# into log files. Required to be on for
# csvlogs.
# (change requires restart)
# These are only used if logging_collector is on:
#log_directory = 'log'          # directory where log files are written,
# can be absolute or relative to PGDATA
#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'    # log file name pattern,
# can include strftime() escapes
#log_file_mode = 0600           # creation mode for log files,
# begin with 0 to use octal notation
#log_truncate_on_rotation = off     # If on, an existing log file with the
# same name as the new log file will be
# truncated rather than appended to.
# But such truncation only occurs on
# time-driven rotation, not on restarts
# or size-driven rotation.  Default is
# off, meaning append to existing files
# in all cases.
#log_rotation_age = 1d          # Automatic rotation of logfiles will
# happen after that time.  0 disables.
#log_rotation_size = 10MB       # Automatic rotation of logfiles will
# happen after that much log output.
# 0 disables.
# These are relevant when logging to syslog:
#syslog_facility = 'LOCAL0'
#syslog_ident = 'postgres'
#syslog_sequence_numbers = on
#syslog_split_messages = on
# This is only relevant when logging to eventlog (win32):
# (change requires restart)
#event_source = 'PostgreSQL'
# - When to Log -
#log_min_messages = warning     # values in order of decreasing detail:
#   debug5
#   debug4
#   debug3
#   debug2
#   debug1
#   info
#   notice
#   warning
#   error
#   log
#   fatal
#   panic
#log_min_error_statement = error    # values in order of decreasing detail:
#   debug5
#   debug4
#   debug3
#   debug2
#   debug1
#   info
#   notice
#   warning
#   error
#   log
#   fatal
#   panic (effectively off)
#log_min_duration_statement = -1    # logs statements and their durations
# according to log_statement_sample_rate. -1 is disabled,
# 0 logs all statement, > 0 logs only statements running at
# least this number of milliseconds.
#log_statement_sample_rate = 1  # Fraction of logged statements over
# log_min_duration_statement. 1.0 logs all statements,
# 0 never logs.
# - What to Log -
#debug_print_parse = off
#debug_print_rewritten = off
#debug_print_plan = off
#debug_pretty_print = on
#log_checkpoints = off
#log_connections = off
#log_disconnections = off
#log_duration = off
#log_error_verbosity = default      # terse, default, or verbose messages
#log_hostname = off
#log_line_prefix = '%m [%p] '       # special values:
#   %a = application name
#   %u = user name
#   %d = database name
#   %r = remote host and port
#   %h = remote host
#   %p = process ID
#   %t = timestamp without milliseconds
#   %m = timestamp with milliseconds
#   %n = timestamp with milliseconds (as a Unix epoch)
#   %i = command tag
#   %e = SQL state
#   %c = session ID
#   %l = session line number
#   %s = session start timestamp
#   %v = virtual transaction ID
#   %x = transaction ID (0 if none)
#   %q = stop here in non-session
#        processes
#   %% = '%'
# e.g. '<%u%%%d> '
#log_lock_waits = off           # log lock waits >= deadlock_timeout
#log_statement = 'none'         # none, ddl, mod, all
#log_replication_commands = off
#log_temp_files = -1            # log temporary files equal or larger
# than the specified size in kilobytes;
# -1 disables, 0 logs all temp files
#log_timezone = 'GMT'
#------------------------------------------------------------------------------
# PROCESS TITLE
#------------------------------------------------------------------------------
#cluster_name = ''          # added to process titles if nonempty
# (change requires restart)
#update_process_title = on
#------------------------------------------------------------------------------
# STATISTICS
#------------------------------------------------------------------------------
# - Query and Index Statistics Collector -
#track_activities = on
#track_counts = on
#track_io_timing = off
#track_functions = none         # none, pl, all
#track_activity_query_size = 1024   # (change requires restart)
#stats_temp_directory = 'pg_stat_tmp'
# - Monitoring -
#log_parser_stats = off
#log_planner_stats = off
#log_executor_stats = off
#log_statement_stats = off
#------------------------------------------------------------------------------
# AUTOVACUUM
#------------------------------------------------------------------------------
#autovacuum = on            # Enable autovacuum subprocess?  'on'
# requires track_counts to also be on.
#log_autovacuum_min_duration = -1   # -1 disables, 0 logs all actions and
# their durations, > 0 logs only
# actions running at least this number
# of milliseconds.
#autovacuum_max_workers = 3     # max number of autovacuum subprocesses
# (change requires restart)
#autovacuum_naptime = 1min      # time between autovacuum runs
#autovacuum_vacuum_threshold = 50   # min number of row updates before
# vacuum
#autovacuum_analyze_threshold = 50  # min number of row updates before
# analyze
#autovacuum_vacuum_scale_factor = 0.2   # fraction of table size before vacuum
#autovacuum_analyze_scale_factor = 0.1  # fraction of table size before analyze
#autovacuum_freeze_max_age = 200000000  # maximum XID age before forced vacuum
# (change requires restart)
#autovacuum_multixact_freeze_max_age = 400000000    # maximum multixact age
# before forced vacuum
# (change requires restart)
#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for
# autovacuum, in milliseconds;
# -1 means use vacuum_cost_delay
#autovacuum_vacuum_cost_limit = -1  # default vacuum cost limit for
# autovacuum, -1 means use
# vacuum_cost_limit
#------------------------------------------------------------------------------
# CLIENT CONNECTION DEFAULTS
#------------------------------------------------------------------------------
# - Statement Behavior -
#client_min_messages = notice       # values in order of decreasing detail:
#   debug5
#   debug4
#   debug3
#   debug2
#   debug1
#   log
#   notice
#   warning
#   error
#search_path = '"$user", public'    # schema names
#row_security = on
#default_tablespace = ''        # a tablespace name, '' uses the default
#temp_tablespaces = ''          # a list of tablespace names, '' uses
# only default tablespace
#check_function_bodies = on
#default_transaction_isolation = 'read committed'
#default_transaction_read_only = off
#default_transaction_deferrable = off
#session_replication_role = 'origin'
#statement_timeout = 0          # in milliseconds, 0 is disabled
#lock_timeout = 0           # in milliseconds, 0 is disabled
#idle_in_transaction_session_timeout = 0    # in milliseconds, 0 is disabled
#vacuum_freeze_min_age = 50000000
#vacuum_freeze_table_age = 150000000
#vacuum_multixact_freeze_min_age = 5000000
#vacuum_multixact_freeze_table_age = 150000000
#vacuum_cleanup_index_scale_factor = 0.1    # fraction of total number of tuples
# before index cleanup, 0 always performs
# index cleanup
#bytea_output = 'hex'           # hex, escape
#xmlbinary = 'base64'
#xmloption = 'content'
#gin_fuzzy_search_limit = 0
#gin_pending_list_limit = 4MB
# - Locale and Formatting -
#datestyle = 'iso, mdy'
#intervalstyle = 'postgres'
#timezone = 'GMT'
#timezone_abbreviations = 'Default'     # Select the set of available time zone
# abbreviations.  Currently, there are
#   Default
#   Australia (historical usage)
#   India
# You can create your own file in
# share/timezonesets/.
#extra_float_digits = 1         # min -15, max 3; any value >0 actually
# selects precise output mode
#client_encoding = sql_ascii        # actually, defaults to database
# encoding
# These settings are initialized by initdb, but they can be changed.
#lc_messages = 'C'          # locale for system error message
# strings
#lc_monetary = 'C'          # locale for monetary formatting
#lc_numeric = 'C'           # locale for number formatting
#lc_time = 'C'              # locale for time formatting
# default configuration for text search
#default_text_search_config = 'pg_catalog.simple'
# - Shared Library Preloading -
#shared_preload_libraries = ''  # (change requires restart)
#local_preload_libraries = ''
#session_preload_libraries = ''
#jit_provider = 'llvmjit'       # JIT library to use
# - Other Defaults -
#dynamic_library_path = '$libdir'
#------------------------------------------------------------------------------
# LOCK MANAGEMENT
#------------------------------------------------------------------------------
#deadlock_timeout = 1s
#max_locks_per_transaction = 64     # min 10
# (change requires restart)
#max_pred_locks_per_transaction = 64    # min 10
# (change requires restart)
#max_pred_locks_per_relation = -2   # negative values mean
# (max_pred_locks_per_transaction
#  / -max_pred_locks_per_relation) - 1
#max_pred_locks_per_page = 2            # min 0
#------------------------------------------------------------------------------
# VERSION AND PLATFORM COMPATIBILITY
#------------------------------------------------------------------------------
# - Previous PostgreSQL Versions -
#array_nulls = on
#backslash_quote = safe_encoding    # on, off, or safe_encoding
#escape_string_warning = on
#lo_compat_privileges = off
#operator_precedence_warning = off
#quote_all_identifiers = off
#standard_conforming_strings = on
#synchronize_seqscans = on
# - Other Platforms and Clients -
#transform_null_equals = off
#------------------------------------------------------------------------------
# ERROR HANDLING
#------------------------------------------------------------------------------
#exit_on_error = off            # terminate session on any error?
#restart_after_crash = on       # reinitialize after backend crash?
#data_sync_retry = off          # retry or panic on failure to fsync
# data?
# (change requires restart)
#------------------------------------------------------------------------------
# CONFIG FILE INCLUDES
#------------------------------------------------------------------------------
# These options allow settings to be loaded from files other than the
# default postgresql.conf.
#include_dir = 'conf.d'         # include files ending in '.conf' from
# directory 'conf.d'
#include_if_exists = 'exists.conf'  # include file only if it exists
#include = 'special.conf'       # include file
#------------------------------------------------------------------------------
# CUSTOMIZED OPTIONS
#------------------------------------------------------------------------------
# Add settings for extensions here

Ин ҳама аст, шумо метавонед контейнерҳоро бо фармон оғоз кунед docker-compose up -d. Ё дар консоли алоҳида бо фармон docker-compose up.

Ҳамин тавр, бастаҳо насб карда шуданд, пойгоҳи додаҳо ба кор андохта шуданд, танҳо он аст, ки онҳо бо ҳамдигар дӯстӣ кунанд. Барои ин, шумо бояд файли зеринро ба решаи лоиҳа илова кунед: ormconfig.js:

ormconfig.js

const process = require('process');
const username = process.env.POSTGRES_USER || "postgres";
const password = process.env.POSTGRES_PASSWORD || "example";
module.exports = {
"type": "postgres",
"host": "localhost",
"port": 5432,
username,
password,
"database": "postgres",
"synchronize": true,
"dropSchema": false,
"logging": true,
"entities": [__dirname + "/src/**/*.entity.ts", __dirname + "/dist/**/*.entity.js"],
"migrations": ["migrations/**/*.ts"],
"subscribers": ["subscriber/**/*.ts", "dist/subscriber/**/.js"],
"cli": {
"entitiesDir": "src",
"migrationsDir": "migrations",
"subscribersDir": "subscriber"
}
}

Ин конфигуратсия барои cli typeorm истифода мешавад.

Биёед ин конфигуратсияро муфассалтар дида бароем. Дар сатрҳои 3 ва 4 мо номи корбар ва паролро аз тағирёбандаҳои муҳити зист мегирем. Ин қулай аст, вақте ки шумо якчанд муҳит доред (dev, stage, prod ва ғайра). Бо нобаёнӣ, номи корбар postgres аст ва парол намуна аст. Қисми боқимондаи конфигуратсия ночиз аст, бинобар ин мо танҳо ба параметрҳои ҷолибтарин тамаркуз хоҳем кард:

  • синхронизатсия - Нишон медиҳад, ки оё схемаи пойгоҳи додаҳо ҳангоми оғози барнома бояд ба таври худкор эҷод карда шавад. Бо ин хосият эҳтиёт шавед ва онро дар истеҳсолот истифода набаред, дар акси ҳол шумо маълумотро гум мекунед. Ин хосият ҳангоми таҳия ва ислоҳи барнома қулай аст. Ҳамчун алтернатива ба ин хосият, шумо метавонед фармонро истифода баред schema:sync аз CLI TypeORM.
  • dropSchema - ҳар дафъае, ки пайвастшавӣ барқарор карда мешавад, схемаро аз нав танзим кунед. Мисли варианти қаблӣ, ин хосият бояд танҳо ҳангоми таҳия ва ислоҳи барнома истифода шавад.
  • объектҳо - кадом роҳҳо барои ҷустуҷӯи тавсифи моделҳо. Лутфан қайд кунед, ки ҷустуҷӯ аз рӯи ниқоб дастгирӣ карда мешавад.
  • cli.entitiesDir феҳристест, ки дар он моделҳои аз TypeORM CLI сохташуда бояд бо нобаёнӣ нигоҳ дошта шаванд.

Барои он ки мо тамоми хусусиятҳои TypeORM-ро дар барномаи Nest истифода барем, мо бояд модулро ворид кунем TypeOrmModule в AppModule. Онхое. шумо AppModule чунин ба назар мерасад:

app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import * as process from "process";
const username = process.env.POSTGRES_USER || 'postgres';
const password = process.env.POSTGRES_PASSWORD || 'example';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username,
password,
database: 'postgres',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true,
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

Тавре ки шумо шояд пай бурдед, усули forRoot ҳамон конфигуратсия барои кор бо пойгоҳи додаҳо, ки дар файли ormconfig.ts интиқол дода мешавад

Ласси ниҳоӣ боқӣ мемонад - якчанд вазифаҳоро барои кор бо TypeORM дар package.json илова кунед. Далели он аст, ки CLI дар JavaScript навишта шудааст ва дар муҳити nodejs кор мекунад. Бо вуҷуди ин, ҳама моделҳо ва муҳоҷирати мо бо хатти чопӣ навишта мешаванд. Аз ин рӯ, пеш аз истифодаи CLI, интиқол ва моделҳои моро интиқол додан лозим аст. Барои ин ба мо бастаи ts-node лозим аст:

yarn add -D ts-node

Баъд аз ин, фармонҳои заруриро ба package.json илова кунед:

"typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js",
"migration:generate": "yarn run typeorm migration:generate -n",
"migration:create": "yarn run typeorm migration:create -n",
"migration:run": "yarn run typeorm migration:run"

Фармони аввал, typeorm, як печи ts-гиреҳро барои иҷро кардани TypeORM cli илова мекунад. Фармонҳои боқимонда миёнабурҳои қулай мебошанд, ки шумо ҳамчун таҳиякунанда қариб ҳар рӯз истифода мебаред:
migration:generate — эҷоди муҳоҷират дар асоси тағирот дар моделҳои шумо.
migration:create — ташкили муҳоҷирати холӣ.
migration:run - оғози муҳоҷират.
Хуб, ҳоло ин аст, мо бастаҳои заруриро илова кардем, барномаро барои кор бо пойгоҳи додаҳо ҳам аз cli ва ҳам аз худи барнома танзим кардем ва инчунин DBMS-ро оғоз кардем. Вақти он расидааст, ки ба замимаи мо мантиқ илова кунем.

Насб кардани бастаҳо барои эҷоди CRUD

Бо истифода аз танҳо Nest, шумо метавонед API эҷод кунед, ки ба шумо имкон медиҳад объектро эҷод, хонед, навсозӣ ва нест кунед. Ин ҳалли ҳарчи бештар чандир хоҳад буд, вале дар баъзе мавридҳо он зиёдатӣ хоҳад буд. Масалан, агар ба шумо лозим ояд, ки прототипро зуд эҷод кунед, шумо метавонед аксар вақт барои суръати рушд чандириро қурбон кунед. Бисёр чаҳорчӯбаҳо барои тавлиди CRUD тавассути тавсифи модели додаҳои як объекти муайян функсияҳоро таъмин мекунанд. Ва Nest истисно нест! Ин функсия аз ҷониби баста таъмин карда мешавад @nestjsx/crud. Имкониятҳои он хеле ҷолибанд:

  • насб ва конфигуратсияи осон;
  • Истиқлолияти DBMS;
  • забони пурқуввати пурсиш бо қобилияти филтр кардан, саҳифабандӣ кардан, ба навъбандӣ кардан, бор кардани муносибатҳо ва объектҳои дохилшуда, кэш ва ғайра;
  • баста барои тавлиди дархостҳо дар фронт;
  • осон кардани усулҳои назораткунанда;
  • конфигуратсияи хурд;
  • дастгирии ҳуҷҷатҳои swagger.

Функсияҳо ба якчанд бастаҳо тақсим мешаванд:

  • @nestjsx/crud - бастаи асосие, ки ороишгар таъмин мекунад Хом() барои тавлиди хатсайр, конфигуратсия ва тасдиқ;
  • @nestjsx/crud-request — маҷмӯае, ки барои истифода дар паҳлӯи пешина дархосткунанда/таҳлилкунандаро таъмин мекунад;
  • @nestjsx/crud-typeorm — маҷмӯа барои ҳамгироӣ бо TypeORM, ки хидмати асосии TypeOrmCrudServiceро бо усулҳои CRUD барои кор бо объектҳо дар пойгоҳи додаҳо таъмин мекунад.

Дар ин дарс ба мо бастаҳо лозиманд лонаjsx/crud ва лонаjsx/crud-typeorm. Аввалан, биёед онҳоро ҷойгир кунем

yarn add @nestjsx/crud class-transformer class-validator

Бастаҳо трансформатори синфй и тасдиқкунандаи синф дар ин замима барои тавсифи декларативии қоидаҳои табдил додани мисолҳои намунавӣ ва тасдиқи дархостҳои воридотӣ заруранд. Ин бастаҳо аз як муаллиф мебошанд, бинобар ин интерфейсҳо монанданд.

Татбиқи мустақими CRUD

Мо ҳамчун намуна рӯйхати корбаронро мегирем. Истифодабарандагон майдонҳои зеринро доранд: id, username, displayName, email. id - майдони худкор афзоишёбанда, email и username - майдонҳои беназир. Ин оддӣ аст! Танҳо амалӣ кардани идеяи мо дар шакли барномаи Nest боқӣ мемонад.
Аввал шумо бояд модул эҷод кунед users, ки барои кор бо истифодабарандагон масъул хоҳад буд. Биёед cli-ро аз NestJS истифода барем ва фармонро дар директорияи решаи лоиҳаи худ иҷро кунем nest g module users.

истифодабарандагони модули nest g

dmitrii@dmitrii-HP-ZBook-17-G3:~/projects/nest-rest git:(master*)$ nest g module users
CREATE /src/users/users.module.ts (82 bytes)
UPDATE /src/app.module.ts (312 bytes)

Дар ин модул мо папкаи объектҳоро илова хоҳем кард, ки дар он моделҳои ин модул дорем. Аз ҷумла, биёед файли user.entity.ts-ро бо тавсифи модели корбар дар ин ҷо илова кунем:

user.entity.ts

import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: string;
@Column({unique: true})
email: string;
@Column({unique: true})
username: string;
@Column({nullable: true})
displayName: string;
}

Барои он ки ин модел аз ҷониби замимаи мо "дида" шавад, дар модул зарур аст UsersModule воридот TypeOrmModule мазмуни зерин:

users.module.ts

import { Module } from '@nestjs/common';
import { UsersController } from './controllers/users/users.controller';
import { UsersService } from './services/users/users.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './entities/user.entity';
@Module({
controllers: [UsersController],
providers: [UsersService],
imports: [
TypeOrmModule.forFeature([User])
]
})
export class UsersModule {}

Яъне, дар ин ҷо воридот мекунем TypeOrmModule, ки дар он ҳамчун параметри усул forFeature Мо рӯйхати моделҳои марбут ба ин модулро нишон медиҳем.

Танҳо эҷоди воҳиди мувофиқ дар пойгоҳи додаҳо боқӣ мемонад. Механизми муҳоҷират ба ин мақсадҳо хизмат мекунад. Барои эҷод кардани муҳоҷират дар асоси тағирот дар моделҳо, шумо бояд фармонро иҷро кунед npm run migration:generate -- CreateUserTable:

Сарлавҳаи спойлер

$ npm run migration:generate -- CreateUserTable
Migration /home/dmitrii/projects/nest-rest/migrations/1563346135367-CreateUserTable.ts has been generated successfully.
Done in 1.96s.

Ба мо лозим набуд, ки муҳоҷиратро дастӣ нависем, ҳама чиз ба таври ҷодугарӣ рӯй дод. Магар ин мӯъҷиза нест! Бо вуҷуди ин, ин ҳама нест. Биёед файли муҳоҷири эҷодшударо бубинем:

1563346135367-CreateUserTable.ts

import {MigrationInterface, QueryRunner} from "typeorm";
export class CreateUserTable1563346816726 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TABLE "user" ("id" SERIAL NOT NULL, "email" character varying NOT NULL, "username" character varying NOT NULL, "displayName" character varying, CONSTRAINT "UQ_e12875dfb3b1d92d7d7c5377e22" UNIQUE ("email"), CONSTRAINT "UQ_78a916df40e02a9deb1c4b75edb" UNIQUE ("username"), CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id"))`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`DROP TABLE "user"`);
}
}

Тавре ки шумо мебинед, на танҳо усули оғози муҳоҷират, балки усули баргардонидани он низ ба таври худкор тавлид шудааст. Фантастика!
Ҳама чиз боқӣ мондааст, ки ин муҳоҷиратро пеш баранд. Ин бо фармони зерин анҷом дода мешавад:

npm run migration:run.

Ин аст, ҳоло тағиротҳои схема ба пойгоҳи додаҳо интиқол дода шуданд.
Баъдан, мо хидматеро эҷод мекунем, ки барои кор бо корбарон масъул аст ва аз он мерос мегирад TypeOrmCrudService. Анбори объекти манфиатдор бояд ба параметри созандаи волидайн интиқол дода шавад, дар ҳолати мо User анбор.

users.service.ts

import { Injectable } from '@nestjs/common';
import { TypeOrmCrudService } from '@nestjsx/crud-typeorm';
import { User } from '../../entities/user.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
@Injectable()
export class UsersService extends TypeOrmCrudService<User>{
constructor(@InjectRepository(User) usersRepository: Repository<User>){
super(usersRepository);
}
}

Мо ба ин хидмат дар контроллер ниёз дорем users. Барои сохтани контроллер, дар консол нависед nest g controller users/controllers/users

лона г корбарон / назоратчиён / истифодабарандагон

dmitrii@dmitrii-HP-ZBook-17-G3:~/projects/nest-rest git:(master*)$ nest g controller users/controllers/users
CREATE /src/users/controllers/users/users.controller.spec.ts (486 bytes)
CREATE /src/users/controllers/users/users.controller.ts (99 bytes)
UPDATE /src/users/users.module.ts (188 bytes)

Биёед ин контроллерро кушоем ва онро таҳрир кунем, то ҷодуе каме илова кунем лонаjsx/crud. Дар як синф UsersController Биёед як ороишгари монанди ин илова кунем:

@Crud({
model: {
type: User
}
})

Хом ороишгаре мебошад, ки ба контроллер усулхои зарурии кор бо модель илова мекунад. Навъи модел дар майдон нишон дода шудааст model.type конфигуратсияҳои ороишгар.
Қадами дуюм татбиқи интерфейс аст CrudController<User>. Рамзи контроллер "Ҷамъшуда" чунин менамояд:

import { Controller } from '@nestjs/common';
import { Crud, CrudController } from '@nestjsx/crud';
import { User } from '../../entities/user.entity';
import { UsersService } from '../../services/users/users.service';
@Crud({
model: {
type: User
}
})
@Controller('users')
export class UsersController implements CrudController<User>{
constructor(public service: UsersService){}
}

Ва ҳамааш! Акнун контроллер тамоми маҷмӯи амалиётҳоро бо модел дастгирӣ мекунад! Ба ман бовар намекунед? Биёед барномаи худро дар амал санҷем!

Сохтани скрипти дархост дар TestMace

Барои санҷидани хидмати мо мо IDE-ро барои кор бо API истифода хоҳем кард TestMace. Чаро TestMace? Дар муқоиса бо маҳсулоти шабеҳ он бартариҳои зерин дорад:

  • кори пурқувват бо тағирёбандаҳо. Дар айни замон якчанд намуди таѓйирёбандањо вуљуд доранд, ки њар яки онњо наќши мушаххас доранд: таѓйирёбандањои дарунсохт, таѓйирёбандањои динамикї, таѓйирёбандањои муњити зист. Ҳар як тағирёбанда ба гиреҳ тааллуқ дорад, ки механизми меросиро дастгирӣ мекунад;
  • Бе барномасозӣ ба осонӣ скриптҳо эҷод кунед. Дар ин бора дар поён муҳокима карда мешавад;
  • формати барои одамон хондашаванда, ки ба шумо имкон медиҳад, ки лоиҳаро дар системаҳои идоракунии версия захира кунед;
  • автопуркунӣ, равшансозии синтаксис, равшансозии арзиши тағирёбанда;
  • Дастгирии тавсифи API бо қобилияти воридот аз Swagger.

Биёед сервери худро бо фармон оғоз кунем npm start ва кӯшиш кунед, ки ба рӯйхати корбарон дастрасӣ пайдо кунед. Рӯйхати корбаронро, мувофиқи конфигуратсияи контролери мо, аз url localhost:3000/users дастрас кардан мумкин аст. Биёед ба ин URL дархост кунем.
Пас аз кор кардани TestMace шумо метавонед интерфейси зеринро бинед:

Эҷоди CRUD зуд бо nest, @nestjsx/crud ва TestMace

Дар тарафи чапи боло дарахти лоиҳа бо гиреҳи реша мавҷуд аст Лоиҳаи. Биёед кӯшиш кунем, ки дархости аввалро барои гирифтани рӯйхати корбарон эҷод кунем. Барои ин мо эҷод мекунем Қадами дархост гиреҳ Ин дар менюи контекстии гиреҳи лоиҳа анҷом дода мешавад Иловаи гиреҳ -> RequestStep.

Эҷоди CRUD зуд бо nest, @nestjsx/crud ва TestMace

Дар майдони URL, localhost:3000/users гузоред ва дархостро иҷро кунед. Мо рамзи 200-ро бо массиви холӣ дар бадани ҷавоб мегирем. Ин фаҳмо аст, мо то ҳол касеро илова накардаем.
Биёед скрипт эҷод кунем, ки қадамҳои зеринро дар бар мегирад:

  1. эҷоди корбар;
  2. дархост барои ID корбари навтаъсис;
  3. тоза кардани идентификати корбар, ки дар қадами 1 сохта шудааст.

Пас, биёед. Барои роҳат, биёед гиреҳеро монанди эҷод кунем Феҳрист. Аслан, ин танҳо ҷузвдонест, ки дар он мо тамоми скриптро захира мекунем. Барои сохтани гиреҳи ҷузвдон, аз менюи контекстии гиреҳ Лоиҳаро интихоб кунед Иловаи гиреҳ -> Папка. Биёед гиреҳро даъват кунем тафтиш-эчод кардан. Дар дохили гиреҳ тафтиш-эчод кардан Биёед дархости аввалини худро барои эҷоди корбар эҷод кунем. Биёед гиреҳи навбунёдро даъват кунем эҷод-корбар. Яъне, дар айни замон иерархияи гиреҳ чунин хоҳад буд:

Эҷоди CRUD зуд бо nest, @nestjsx/crud ва TestMace

Биёед ба ҷадвали кушода равем эҷод-корбар гиреҳ. Биёед параметрҳои зеринро барои дархост ворид кунем:

  • Навъи дархост - POST
  • URL - localhost: 3000/истифодабарандагон
  • Бадан - JSON бо арзиш {"email": "[email protected]", "displayName": "New user", "username": "user"}

Биёед ин дархостро иҷро кунем. Аризаи мо мегӯяд, ки сабт офарида шудааст.

Эҷоди CRUD зуд бо nest, @nestjsx/crud ва TestMace

Хуб, биёед ин фактро тафтиш кунем. Барои бо идентификатсияи корбари сохташуда дар қадамҳои минбаъда кор кардан, ин параметр бояд захира карда шавад. Механизм барои ин комил аст. тағирёбандаҳои динамикӣ. Биёед мисоли худро истифода барем, то бо онҳо чӣ гуна кор карданро бубинем. Дар ҷадвали таҳлилшудаи ҷавоб, дар паҳлӯи гиреҳи id дар менюи контекстӣ, ҷузъро интихоб кунед Ба тағирёбанда таъин кунед. Дар равзанаи муколама шумо бояд параметрҳои зеринро таъин кунед:

  • Нод — дар кадоме аз аҷдодҳо як тағирёбандаи динамикӣ эҷод кардан. Биёед интихоб кунем тафтиш-эчод кардан
  • Номаълум аст - номи ин тағирёбанда. Биёед занг занем userId.

Ин аст раванди эҷоди тағирёбандаи динамикӣ чӣ гуна аст:

Эҷоди CRUD зуд бо nest, @nestjsx/crud ва TestMace

Ҳоло, ҳар дафъае, ки ин дархост иҷро карда мешавад, арзиши тағирёбандаи динамикӣ нав карда мешавад. Ва азбаски тағирёбандаҳои динамикӣ механизми мероси иерархӣ, тағирёбандаро дастгирӣ мекунанд userId дар наслҳо дастрас хоҳад шуд тафтиш-эчод кардан гиреҳи ҳама гуна сатҳи лона.
Ин тағирёбанда барои мо дар дархости навбатӣ муфид хоҳад буд. Маҳз, мо корбари навтаъсисро дархост хоҳем кард. Ҳамчун фарзанди гиреҳ тафтиш-эчод кардан мо дархост эҷод мекунем санҷед, ки оё вуҷуд дорад бо параметр url баробар localhost:3000/users/${$dynamicVar.userId}. Дизайнро дидан ${variable_name} ин гирифтани арзиши тағирёбанда аст. Зеро Мо як тағирёбандаи динамикӣ дорем, бинобар ин барои ба даст овардани он шумо бояд ба объект дастрасӣ пайдо кунед $dynamicVar, яъне дастрасии пурра ба тағирёбандаи динамикӣ userId чунин менамояд ${$dynamicVar.userId}. Биёед дархостро иҷро кунем ва боварӣ ҳосил кунем, ки маълумот дуруст дархост шудааст.
Қадами охирини боқимонда ин дархости нест кардан аст. Мо ба он на танҳо барои тафтиши амалиёти ҳазф кардан лозим аст, балки инчунин, ба ибораи дигар, пас аз худамон дар пойгоҳи додаҳо тоза кардан лозим аст, зеро Майдонҳои почтаи электронӣ ва номи корбар беназиранд. Ҳамин тавр, дар гиреҳи чек-эҷод мо дархости нест кардани корбарро бо параметрҳои зерин эҷод мекунем

  • Навъи дархост - НАЗОРАТ
  • url - localhost:3000/users/${$dynamicVar.userId}

Биёед оғоз кунем. Мо интизорем. Мо аз натиҷа лаззат мебарем)

Хуб, ҳоло мо метавонем ин скриптро дар вақти дилхоҳ иҷро кунем. Барои иҷро кардани скрипт шумо бояд аз менюи контекстӣ интихоб кунед тафтиш-эчод кардан ҷузъи гиреҳ давидан.

Эҷоди CRUD зуд бо nest, @nestjsx/crud ва TestMace

Гиреҳҳо дар скрипт яке паси дигар иҷро карда мешаванд
Шумо метавонед ин скриптро дар лоиҳаи худ тавассути иҷро захира кунед Файл -> Захираи лоиҳа.

хулоса

Ҳама хусусиятҳои асбобҳои истифодашуда ба формати ин мақола мувофиқат карда наметавонанд. Дар хусуси гунахкори асосй бошад — пакет лонаjsx/crud - мавзӯъҳои зерин кушода боқӣ мемонанд:

  • тасдиқи фармоишӣ ва тағир додани моделҳо;
  • забони пурқуввати дархост ва истифодаи қулайи он дар пеш;
  • аз нав муайян кардан ва илова кардани усулҳои нав ба контроллерҳо;
  • дастгирии пурқувват;
  • идоракунии кэш.

Аммо, ҳатто он чизе, ки дар мақола тавсиф шудааст, барои фаҳмидани он кифоя аст, ки ҳатто чунин чаҳорчӯбаи корхона ба монанди NestJS дорои асбобҳои прототипсозии босуръати барнома мебошад. Ва чунин як IDE олиҷаноб монанди TestMace ба шумо имкон медиҳад, ки суръати додашударо нигоҳ доред.

Рамзи манбаъ барои ин мақола, дар якҷоягӣ бо лоиҳа TestMace, дар анбор дастрас аст https://github.com/TestMace/nest-rest. Барои кушодани лоиҳа TestMace онро танҳо дар барнома иҷро кунед Файл -> Лоиҳаи кушода.

Манбаъ: will.com

Илова Эзоҳ