Exemplarische Vorgehensweise - Teil 2 - Konstrukte für AWS S-Lösungen

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Exemplarische Vorgehensweise - Teil 2

Anmerkung

AWS Solutions Constructs wird in AWS CDK-Versionen ≥ 1.46.0 unterstützt.

In diesem Tutorial erfahren Sie, wie Sie die App „Hello Constructs“ ändern, die inTeil 1. Unsere Änderung fügt einen Site-Trefferzähler hinzu, der das AWS Lambda zu DynamoDB Muster von AWS Solutions Constructs verwendet. Das Ändern der Hello Constructs App führt zu der folgenden Lösung:

Lambda Code

Beginnen wir mit dem Schreiben des Codes für die Funktion Hit Counter AWS Lambda. Diese Funktion wird Folgendes:

  • Inkrementieren Sie einen Leistungsindikator, der sich auf den API-Pfad in einer Amazon DynamoDB -Tabelle bezieht,

  • die Downstream-Funktion „Hello AWS Lambda“ aufrufen

  • und geben Sie die Antwort an den Endbenutzer zurück.

TypeScript

Hinzufügen einer Dateilambda/hitcounter.js-Angabe mit folgendem Inhalt:

const { DynamoDB, Lambda } = require('aws-sdk'); exports.handler = async function(event) { console.log("request:", JSON.stringify(event, undefined, 2)); // create AWS SDK clients const dynamo = new DynamoDB(); const lambda = new Lambda(); // update dynamo entry for "path" with hits++ await dynamo.updateItem({ TableName: process.env.DDB_TABLE_NAME, Key: { path: { S: event.path } }, UpdateExpression: 'ADD hits :incr', ExpressionAttributeValues: { ':incr': { N: '1' } } }).promise(); // call downstream function and capture response const resp = await lambda.invoke({ FunctionName: process.env.DOWNSTREAM_FUNCTION_NAME, Payload: JSON.stringify(event) }).promise(); console.log('downstream response:', JSON.stringify(resp, undefined, 2)); // return response back to upstream caller return JSON.parse(resp.Payload); };
Python

Hinzufügen einer Dateilambda/hitcounter.py-Angabe mit folgendem Inhalt:

import json import os import boto3 ddb = boto3.resource('dynamodb') table = ddb.Table(os.environ['DDB_TABLE_NAME']) _lambda = boto3.client('lambda') def handler(event, context): print('request: {}'.format(json.dumps(event))) table.update_item( Key={'path': event['path']}, UpdateExpression='ADD hits :incr', ExpressionAttributeValues={':incr': 1} ) resp = _lambda.invoke( FunctionName=os.environ['DOWNSTREAM_FUNCTION_NAME'], Payload=json.dumps(event), ) body = resp['Payload'].read() print('downstream response: {}'.format(body)) return json.loads(body)

Installieren der neuen Abhängigkeiten

Anmerkung

Denken Sie daran, die richtige, übereinstimmende Version zu ersetzen, die sowohl für AWS Lösungskonstrukte als auch für das AWS-CDK verwendet werden soll, in dasVERSION_NUMBERPlatzhalterfelder für jeden Befehl. Dies sollte identisch mit der Versionsnummer sein, die für Abhängigkeiten im ersten Teil dieser exemplarischen Vorgehensweise verwendet wird. Fehlübereinstimmende Versionen zwischen Paketen können zu Fehlern führen.

Wie üblich müssen wir zuerst die Abhängigkeiten installieren, die wir für unser Lösungsupdate benötigen. Zuerst müssen wir die DynamoDB Konstruktionsbibliothek installieren:

TypeScript
npm install -s @aws-cdk/aws-dynamodb@VERSION_NUMBER
Python
pip install aws_cdk.aws_dynamodb==VERSION_NUMBER

Installieren Sie schließlich die AWS Solutions Constructsaws-lambda-dynamodbModul und alle seine Abhängigkeiten in unser Projekt:

TypeScript
npm install -s @aws-solutions-constructs/aws-lambda-dynamodb@VERSION_NUMBER
Python
pip install aws_solutions_constructs.aws_lambda_dynamodb==VERSION_NUMBER

Definieren der Ressourcen

Aktualisieren wir nun unseren Stack-Code, um unsere neue Architektur zu berücksichtigen.

Zuerst werden wir unsere neuen Abhängigkeiten importieren und die Funktion „Hallo“ außerhalb desaws-apigateway-lambdaMuster, das wir in Teil 1 erstellt haben.

TypeScript

Bearbeiten Sie die Dateilib/hello-constructs.tsFolgendes:

import * as cdk from '@aws-cdk/core'; import * as lambda from '@aws-cdk/aws-lambda'; import * as api from '@aws-cdk/aws-apigateway'; import * as dynamodb from '@aws-cdk/aws-dynamodb'; import { ApiGatewayToLambda, ApiGatewayToLambdaProps } from '@aws-solutions-constructs/aws-apigateway-lambda'; import { LambdaToDynamoDB, LambdaToDynamoDBProps } from '@aws-solutions-constructs/aws-lambda-dynamodb'; export class HelloConstructsStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // The code that defines your stack goes here const helloFunc = new lambda.Function(this, 'HelloHandler', { runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('lambda'), handler: 'hello.handler' }); const api_lambda_props: ApiGatewayToLambdaProps = { lambdaFunctionProps: { code: lambda.Code.fromAsset('lambda'), runtime: lambda.Runtime.NODEJS_12_X, handler: 'hello.handler' }, apiGatewayProps: { defaultMethodOptions: { authorizationType: api.AuthorizationType.NONE } } }; new ApiGatewayToLambda(this, 'ApiGatewayToLambda', api_lambda_props); } }
Python

Bearbeiten Sie die Dateihello_constructs/hello_constructs_stack.pyFolgendes:

from aws_cdk import ( aws_lambda as _lambda, aws_apigateway as apigw, aws_dynamodb as ddb, core, ) from aws_solutions_constructs import ( aws_apigateway_lambda as apigw_lambda, aws_lambda_dynamodb as lambda_ddb ) class HelloConstructsStack(core.Stack): def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # The code that defines your stack goes here self._handler = _lambda.Function( self, 'HelloHandler', runtime=_lambda.Runtime.PYTHON_3_7, handler='hello.handler', code=_lambda.Code.asset('lambda'), ) apigw_lambda.ApiGatewayToLambda( self, 'ApiGatewayToLambda', lambda_function_props=_lambda.FunctionProps( runtime=_lambda.Runtime.PYTHON_3_7, code=_lambda.Code.asset('lambda'), handler='hello.handler', ), api_gateway_props=apigw.RestApiProps( default_method_options=apigw.MethodOptions( authorization_type=apigw.AuthorizationType.NONE ) ) )

Als nächstes fügen wir dieaws-lambda-dynamodb-Muster, um den Hitzähler-Service für unsere aktualisierte Architektur aufzubauen.

Das nächste Update unten definiert die Eigenschaften für dieaws-lambda-dynamodb-Muster, indem Sie die AWS Lambda Funktion mit dem Hit Counter-Handler definieren. Darüber hinaus ist die Amazon DynamoDB -Tabelle mit dem NamenHitsund einen Partitionsschlüssel vonpath.

TypeScript

Bearbeiten Sie die Dateilib/hello-constructs.tsFolgendes:

import * as cdk from '@aws-cdk/core'; import * as lambda from '@aws-cdk/aws-lambda'; import * as api from '@aws-cdk/aws-apigateway'; import * as dynamodb from '@aws-cdk/aws-dynamodb'; import { ApiGatewayToLambda, ApiGatewayToLambdaProps } from '@aws-solutions-constructs/aws-apigateway-lambda'; import { LambdaToDynamoDB, LambdaToDynamoDBProps } from '@aws-solutions-constructs/aws-lambda-dynamodb'; export class HelloConstructsStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // The code that defines your stack goes here const helloFunc = new lambda.Function(this, 'HelloHandler', { runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('lambda'), handler: 'hello.handler' }); // hit counter, aws-lambda-dynamodb pattern const lambda_ddb_props: LambdaToDynamoDBProps = { lambdaFunctionProps: { code: lambda.Code.asset(`lambda`), runtime: lambda.Runtime.NODEJS_12_X, handler: 'hitcounter.handler', environment: { DOWNSTREAM_FUNCTION_NAME: helloFunc.functionName } }, dynamoTableProps: { tableName: 'Hits', partitionKey: { name: 'path', type: dynamodb.AttributeType.STRING } } }; const hitcounter = new LambdaToDynamoDB(this, 'LambdaToDynamoDB', lambda_ddb_props); const api_lambda_props: ApiGatewayToLambdaProps = { lambdaFunctionProps: { code: lambda.Code.fromAsset('lambda'), runtime: lambda.Runtime.NODEJS_12_X, handler: 'hello.handler' }, apiGatewayProps: { defaultMethodOptions: { authorizationType: api.AuthorizationType.NONE } } }; new ApiGatewayToLambda(this, 'ApiGatewayToLambda', api_lambda_props); } }
Python

Bearbeiten Sie die Dateihello_constructs/hello_constructs_stack.pyFolgendes:

from aws_cdk import ( aws_lambda as _lambda, aws_apigateway as apigw, aws_dynamodb as ddb, core, ) from aws_solutions_constructs import ( aws_apigateway_lambda as apigw_lambda, aws_lambda_dynamodb as lambda_ddb ) class HelloConstructsStack(core.Stack): def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # The code that defines your stack goes here self.hello_func = _lambda.Function( self, 'HelloHandler', runtime=_lambda.Runtime.PYTHON_3_7, handler='hello.handler', code=_lambda.Code.asset('lambda'), ) # hit counter, aws-lambda-dynamodb pattern self.hit_counter = lambda_ddb.LambdaToDynamoDB( self, 'LambdaToDynamoDB', lambda_function_props=_lambda.FunctionProps( runtime=_lambda.Runtime.PYTHON_3_7, code=_lambda.Code.asset('lambda'), handler='hitcounter.handler', environment={ 'DOWNSTREAM_FUNCTION_NAME': self.hello_func.function_name } ), dynamo_table_props=ddb.TableProps( table_name='Hits', partition_key={ 'name': 'path', 'type': ddb.AttributeType.STRING } ) ) apigw_lambda.ApiGatewayToLambda( self, 'ApiGatewayToLambda', lambda_function_props=_lambda.FunctionProps( runtime=_lambda.Runtime.PYTHON_3_7, code=_lambda.Code.asset('lambda'), handler='hello.handler', ), api_gateway_props=apigw.RestApiProps( default_method_options=apigw.MethodOptions( authorization_type=apigw.AuthorizationType.NONE ) ) )

Als Nächstes müssen wir die Trefferzähler-Funktion gewähren, die aus demaws-lambda-dynamodbMuster hinzugefügt oben Berechtigung, unsere Hello Funktion aufzurufen.

TypeScript

Bearbeiten Sie die Dateilib/hello-constructs.tsFolgendes:

import * as cdk from '@aws-cdk/core'; import * as lambda from '@aws-cdk/aws-lambda'; import * as api from '@aws-cdk/aws-apigateway'; import * as dynamodb from '@aws-cdk/aws-dynamodb'; import { ApiGatewayToLambda, ApiGatewayToLambdaProps } from '@aws-solutions-constructs/aws-apigateway-lambda'; import { LambdaToDynamoDB, LambdaToDynamoDBProps } from '@aws-solutions-constructs/aws-lambda-dynamodb'; export class HelloConstructsStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // The code that defines your stack goes here // hello function responding to http requests const helloFunc = new lambda.Function(this, 'HelloHandler', { runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('lambda'), handler: 'hello.handler' }); // hit counter, aws-lambda-dynamodb pattern const lambda_ddb_props: LambdaToDynamoDBProps = { lambdaFunctionProps: { code: lambda.Code.asset(`lambda`), runtime: lambda.Runtime.NODEJS_12_X, handler: 'hitcounter.handler', environment: { DOWNSTREAM_FUNCTION_NAME: helloFunc.functionName } }, dynamoTableProps: { tableName: 'Hits', partitionKey: { name: 'path', type: dynamodb.AttributeType.STRING } } }; const hitcounter = new LambdaToDynamoDB(this, 'LambdaToDynamoDB', lambda_ddb_props); // grant the hitcounter lambda role invoke permissions to the hello function helloFunc.grantInvoke(hitcounter.lambdaFunction); const api_lambda_props: ApiGatewayToLambdaProps = { lambdaFunctionProps: { code: lambda.Code.fromAsset('lambda'), runtime: lambda.Runtime.NODEJS_12_X, handler: 'hello.handler' }, apiGatewayProps: { defaultMethodOptions: { authorizationType: api.AuthorizationType.NONE } } }; new ApiGatewayToLambda(this, 'ApiGatewayToLambda', api_lambda_props); } }
Python

Bearbeiten Sie die Dateihello_constructs/hello_constructs_stack.pyFolgendes:

from aws_cdk import ( aws_lambda as _lambda, aws_apigateway as apigw, aws_dynamodb as ddb, core, ) from aws_solutions_constructs import ( aws_apigateway_lambda as apigw_lambda, aws_lambda_dynamodb as lambda_ddb ) class HelloConstructsStack(core.Stack): def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # The code that defines your stack goes here self.hello_func = _lambda.Function( self, 'HelloHandler', runtime=_lambda.Runtime.PYTHON_3_7, handler='hello.handler', code=_lambda.Code.asset('lambda'), ) # hit counter, aws-lambda-dynamodb pattern self.hit_counter = lambda_ddb.LambdaToDynamoDB( self, 'LambdaToDynamoDB', lambda_function_props=_lambda.FunctionProps( runtime=_lambda.Runtime.PYTHON_3_7, code=_lambda.Code.asset('lambda'), handler='hitcounter.handler', environment={ 'DOWNSTREAM_FUNCTION_NAME': self.hello_func.function_name } ), dynamo_table_props=ddb.TableProps( table_name='Hits', partition_key={ 'name': 'path', 'type': ddb.AttributeType.STRING } ) ) # grant the hitcounter lambda role invoke permissions to the hello function self.hello_func.grant_invoke(self.hit_counter.lambda_function) apigw_lambda.ApiGatewayToLambda( self, 'ApiGatewayToLambda', lambda_function_props=_lambda.FunctionProps( runtime=_lambda.Runtime.PYTHON_3_7, code=_lambda.Code.asset('lambda'), handler='hello.handler', ), api_gateway_props=apigw.RestApiProps( default_method_options=apigw.MethodOptions( authorization_type=apigw.AuthorizationType.NONE ) ) )

Schließlich müssen wir unsere ursprünglicheaws-apigateway-lambda-Muster verwenden, um unsere neue Trefferzähler-Funktion zu verwenden, die mit deraws-lambda-dynamodbMuster oben.

TypeScript

Bearbeiten Sie die Dateilib/hello-constructs.tsFolgendes:

import * as cdk from '@aws-cdk/core'; import * as lambda from '@aws-cdk/aws-lambda'; import * as api from '@aws-cdk/aws-apigateway'; import * as dynamodb from '@aws-cdk/aws-dynamodb'; import { ApiGatewayToLambda, ApiGatewayToLambdaProps } from '@aws-solutions-constructs/aws-apigateway-lambda'; import { LambdaToDynamoDB, LambdaToDynamoDBProps } from '@aws-solutions-constructs/aws-lambda-dynamodb'; export class HelloConstructsStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // The code that defines your stack goes here // hello function responding to http requests const helloFunc = new lambda.Function(this, 'HelloHandler', { runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('lambda'), handler: 'hello.handler' }); // hit counter, aws-lambda-dynamodb pattern const lambda_ddb_props: LambdaToDynamoDBProps = { lambdaFunctionProps: { code: lambda.Code.asset(`lambda`), runtime: lambda.Runtime.NODEJS_12_X, handler: 'hitcounter.handler', environment: { DOWNSTREAM_FUNCTION_NAME: helloFunc.functionName } }, dynamoTableProps: { tableName: 'Hits', partitionKey: { name: 'path', type: dynamodb.AttributeType.STRING } } }; const hitcounter = new LambdaToDynamoDB(this, 'LambdaToDynamoDB', lambda_ddb_props); // grant the hitcounter lambda role invoke permissions to the hello function helloFunc.grantInvoke(hitcounter.lambdaFunction); const api_lambda_props: ApiGatewayToLambdaProps = { existingLambdaObj: hitcounter.lambdaFunction, apiGatewayProps: { defaultMethodOptions: { authorizationType: api.AuthorizationType.NONE } } }; new ApiGatewayToLambda(this, 'ApiGatewayToLambda', api_lambda_props); } }
Python

Bearbeiten Sie die Dateihello_constructs/hello_constructs_stack.pyFolgendes:

from aws_cdk import ( aws_lambda as _lambda, aws_apigateway as apigw, aws_dynamodb as ddb, core, ) from aws_solutions_constructs import ( aws_apigateway_lambda as apigw_lambda, aws_lambda_dynamodb as lambda_ddb ) class HelloConstructsStack(core.Stack): def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # The code that defines your stack goes here self.hello_func = _lambda.Function( self, 'HelloHandler', runtime=_lambda.Runtime.PYTHON_3_7, handler='hello.handler', code=_lambda.Code.asset('lambda'), ) # hit counter, aws-lambda-dynamodb pattern self.hit_counter = lambda_ddb.LambdaToDynamoDB( self, 'LambdaToDynamoDB', lambda_function_props=_lambda.FunctionProps( runtime=_lambda.Runtime.PYTHON_3_7, code=_lambda.Code.asset('lambda'), handler='hitcounter.handler', environment={ 'DOWNSTREAM_FUNCTION_NAME': self.hello_func.function_name } ), dynamo_table_props=ddb.TableProps( table_name='Hits', partition_key={ 'name': 'path', 'type': ddb.AttributeType.STRING } ) ) # grant the hitcounter lambda role invoke permissions to the hello function self.hello_func.grant_invoke(self.hit_counter.lambda_function) apigw_lambda.ApiGatewayToLambda( self, 'ApiGatewayToLambda', existing_lambda_obj=self.hit_counter.lambda_function, api_gateway_props=apigw.RestApiProps( default_method_options=apigw.MethodOptions( authorization_type=apigw.AuthorizationType.NONE ) ) )

Überprüfen Sie die Änderungen.

Lassen Sie uns unser Projekt erstellen und die Änderungen an unseren Ressourcen überprüfen, die passieren, wenn wir dies bereitstellen:

npm run build cdk diff

Unsere Ausgabe sollte wie folgt aussehen:

Stack HelloConstructsStack
IAM Statement Changes
┌───┬───────────────────────────────────┬────────┬───────────────────────────────────┬────────────────────────────────────┬───────────┐
│   │ Resource                          │ Effect │ Action                            │ Principal                          │ Condition │
├───┼───────────────────────────────────┼────────┼───────────────────────────────────┼────────────────────────────────────┼───────────┤
│ + │ ${HelloHandler.Arn}               │ Allow  │ lambda:InvokeFunction             │ AWS:${LambdaFunctionServiceRole}   │           │
├───┼───────────────────────────────────┼────────┼───────────────────────────────────┼────────────────────────────────────┼───────────┤
│ + │ ${HelloHandler/ServiceRole.Arn}   │ Allow  │ sts:AssumeRole                    │ Service:lambda.amazonaws.com       │           │
├───┼───────────────────────────────────┼────────┼───────────────────────────────────┼────────────────────────────────────┼───────────┤
│ + │ ${LambdaToDynamoDB/DynamoTable.Ar │ Allow  │ dynamodb:BatchGetItem             │ AWS:${LambdaFunctionServiceRole}   │           │
│   │ n}                                │        │ dynamodb:BatchWriteItem           │                                    │           │
│   │                                   │        │ dynamodb:DeleteItem               │                                    │           │
│   │                                   │        │ dynamodb:GetItem                  │                                    │           │
│   │                                   │        │ dynamodb:GetRecords               │                                    │           │
│   │                                   │        │ dynamodb:GetShardIterator         │                                    │           │
│   │                                   │        │ dynamodb:PutItem                  │                                    │           │
│   │                                   │        │ dynamodb:Query                    │                                    │           │
│   │                                   │        │ dynamodb:Scan                     │                                    │           │
│   │                                   │        │ dynamodb:UpdateItem               │                                    │           │
└───┴───────────────────────────────────┴────────┴───────────────────────────────────┴────────────────────────────────────┴───────────┘
IAM Policy Changes
┌───┬─────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐
│   │ Resource                    │ Managed Policy ARN                                                             │
├───┼─────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤
│ + │ ${HelloHandler/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │
└───┴─────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Resources
[+] AWS::IAM::Role HelloHandler/ServiceRole HelloHandlerServiceRole11EF7C63 
[+] AWS::Lambda::Function HelloHandler HelloHandler2E4FBA4D 
[+] AWS::DynamoDB::Table LambdaToDynamoDB/DynamoTable LambdaToDynamoDBDynamoTable53C1442D 
[+] AWS::IAM::Policy LambdaFunctionServiceRole/DefaultPolicy LambdaFunctionServiceRoleDefaultPolicy126C8897 
[~] AWS::Lambda::Function LambdaFunction LambdaFunctionBF21E41F 
 ├─ [+] Environment
 │   └─ {"Variables":{"DOWNSTREAM_FUNCTION_NAME":{"Ref":"HelloHandler2E4FBA4D"},"DDB_TABLE_NAME":{"Ref":"LambdaToDynamoDBDynamoTable53C1442D"}}}
 ├─ [~] Handler
 │   ├─ [-] hello.handler
 │   └─ [+] hitcounter.handler
 └─ [~] DependsOn
     └─ @@ -1,3 +1,4 @@
        [ ] [
        [+]   "LambdaFunctionServiceRoleDefaultPolicy126C8897",
        [ ]   "LambdaFunctionServiceRole0C4CDE0B"
        [ ] ]

cdk-Bereitstellen

Okay, bereit für die Bereitstellung?

cdk deploy

Stack-Ausgabe

Wenn die Bereitstellung abgeschlossen ist, werden Sie folgende Zeile bemerken:

Outputs:
HelloConstructsStack.RestApiEndpoint0551178A = https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod/

Testen Ihrer Anwendung

Lassen Sie uns versuchen, diesen Endpunkt mit curl zu treffen. Kopieren Sie die URL und führen Sie sie aus (Ihr Präfix und Ihre Region werden wahrscheinlich anders sein).

curl https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod/

Die Ausgabe sollte wie folgt aussehen:

Hello, AWS Solutions Constructs! You've hit /

Rufen Sie jetzt dieHitsAmazon DynamoDB -Tabelle.

  1. Rufen Sie die DynamoDB Konsole auf.

  2. Stellen Sie sicher, dass Sie sich in der Region befinden, in der Sie die Tabelle erstellt haben.

  3. SelectTabellenKlicken Sie im Navigationsbereich auf und wählen Sie die OptionTreffer-Tabelle.

  4. Öffnen Sie die Tabelle und wählen Sie „Items“.

  5. Sie sollten sehen, wie viele Treffer Sie für jeden Pfad haben.

  6. Versuchen Sie, einen neuen Pfad zu treffen, und aktualisieren Sie die Ansicht Elemente. Sie sollten ein neues Element mit einemhitsAnzahl von eins.

Wenn dies die Ausgabe ist, die Sie erhalten haben, funktioniert Ihre App!