---
schema_version: "1"
id: d7aff7d85d451d3f3e51a8ea2d09b06456a074c2685d5bb6d564cbf7d4459a2b
title: 出力メタデータ
collection: mulesoft
version: current
locale: ja-jp
portal_url: https://docs.salesforce.com/mulesoft/current/ja-jp/mule-sdk/1.1/metadata-output.md
canonical_url: https://docs.mulesoft.com/jp/mule-sdk/1.1/metadata-output
source_site: docs.mulesoft.com
content_type: documentation
content_hash: 8f5826e7c51106ee7937f7bc8ef484a7523064432b43bf86a4a5162109978e10
description: MuleSoft Documentation Site
release: "1.1"
latest: false
---
# 出力メタデータ

出力メタデータは、コンポーネントの結果の型を解決します。各コンポーネントは、ペイロードと属性の静的メタデータまたは動的メタデータを互いに分離して提供できます。

## [](#outputtyperesolver-と-attributestyperesolver-の宣言)OutputTypeResolver と AttributesTypeResolver の宣言

`OutputTypeResolver`​ 実装と ​`AttributesTypeResolver`​ 実装は、​`MetadataContext`​ が提供する情報に基づいて、また、最も重要な点として ​`MetadataKey`​ を使用してエンドユーザー (Mule アプリケーションの作成者) が必要とする ​`MetadataType`​ を特定することによって、​`MetadataType`​ の解決要求を処理します。​`MetadataType`​ の詳細は、​[「コンポーネントのメタデータとは?」](https://docs.mulesoft.com/jp/mule-sdk/1.1/metadata#component-metadata)​を参照してください。

`OutputTypeResolver<T>`​ インターフェースと ​`AttributesTypeResolver<T>`​ インターフェースは、汎用 ​`T`​ でパラメーター化され、​`MetadataKeyId`​ パラメーターの型と一致する必要があります。この例では、最も一般的な ​`MetadataKeyId`​ 型である ​`String`​ を汎用型として使用しています。(他のドキュメントもこの汎用型を参照し、​`String`​ 以外に変更する必要がある場合に型を詳細に定義しています。)

```java
public class OutputEntityResolver
  implements OutputTypeResolver<String>, AttributesTypeResolver<String>  {

  @Override
  public String getCategoryName() {
    return "Records";
  }

  @Override
  public String getResolverName() {
    return "OutputEntityResolver";
  }

  @Override
  public MetadataType getOutputType(MetadataContext context, String key)
      throws MetadataResolvingException, ConnectionException {
    switch (key) {
      case "Author_id":
        return context.getTypeLoader().load(AuthorResult.class);
      case "BookList_id":
        return context.getTypeLoader().load(BookListResult.class);
      case "Book_id":
        return context.getTypeLoader().load(BookResult.class);
      default:
        throw new MetadataResolvingException("Unknown key:" + key, INVALID_METADATA_KEY);
    }
  }

  @Override
  public MetadataType getAttributesType(MetadataContext context, String key)
      throws MetadataResolvingException, ConnectionException {

    if ("Book_id".equals(key)){
      return context.getTypeLoader().load(BookAttributes.class);
    }

    // Only Books have Attributes information
    return context.getTypeBuilder().nullType().build();
  }

}
```

上記の例では、​`typeLoader`​ を取得するために ​`MetadataContext`​ のみを使用して Java クラスに基づいて MetadataType を記述していますが、提供されている設定要素や接続要素を使用することもできます。

## [](#outputtyperesolver-の使用)OutputTypeResolver の使用

`TypeKeysResolver`​ と ​`OutputTypeResolver`​ を使用することで、操作とソースに出力 DataSense サポートを追加できます。​`OutputTypeResolver`​ と特定の ​`TypeKeysResolver`​ を一緒に使用する場合の主な制限は、​`TypeKeysResolver`​ で提供される ​`MetadataKey`​ が ​`OutputTypeResolver`​ によって ​`MetadataType`​ に解決できるようにするため、どちらも同じ ​`category`​ に属している必要があるという点です。

### [](#結果ペイロードへの-datasense-の追加)結果ペイロードへの DataSense の追加

```java
public class FetchOperations {

  @OutputResolver(output = OutputEntityResolver.class)
  public Map<String,Object> get(@Connection MyConnection connection,
                                @MetadataKeyId(EntityKeysResolver.class) String entityKind){

    return connection.getClient().fetch(entityKind);
  }

}
```

上記の例では、フェッチされる ​`entityKind`​ に基づいて出力の MetadataType を動的に解決しているため、​`EntityKeysResolver`​ が提供する ​`Author_id`​ で ​`entityKind`​ を設定してある場合は、その ​`MetadataKey`​ で ​`OutputEntityResolver`​ が呼び出され、​`get`​ 操作の出力は ​`AuthorResult`​ ObjectType に解決されます。

ソースは、同じ出力型解決を使用して、フローにディスパッチされるオブジェクトの MetadataType を記述することができます。宣言は同様です。

```java
@MetadataScope(keysResolver = EntityKeysResolver.class,
               outputResolver = OutputEntityResolver.class)
public class ListenerSource extends Source<Map<String, Object>, Void>  {

  @MetadataKeyId
  @Parameter
  public String type;

  @Connection
  private ConnectionProvider<MetadataConnection> connection;

  @Override
  public void onStart(SourceCallback<Map<String, Object>, Void> sourceCallback) throws MuleException {
    //...
  }

  @Override
  public void onStop() {
    //...
  }

}
```

ソースと操作では、出力型の解決のライフサイクルは同じです。まず ​`MetadataKeyId`​ を設定してから、そのキーで ​`OutputTypeResolver`​ を呼び出して、結果のエンティティの MetadataType を解決します。

### [](#結果属性用の-datasense-の追加)結果属性用の DataSense の追加

動的メタデータの解決では、コンポーネントの完全な出力がペイロードだけではなく ​`Result<Payload, Attributes>`​ であることを考慮します。

操作またはソースの出力に動的な属性構造がある場合は、​`AttributesTypeResolver`​ (​`OutputTypeResolver.java`​ の例で実装済み) を宣言してから、操作またはソースの宣言にリゾルバーへの参照を追加することで、MetadataType を解決することができます。

次の例では、​`Book`​ エンティティを、それぞれが独自の構造を持つ本のコンテンツと属性に分割します。この分割により、エンドユーザーは操作の結果をより効果的に理解して使用できます。つまり、データ (ペイロードに格納される本のコンテンツ) とペイロードを特徴付けるメタデータ (本の属性) に分けて考えることができます。

```java
public class FetchOperationsWithAttributes {

  @OutputResolver(output = OutputEntityResolver.class,
                  attributes = OutputEntityResolver.class)
  public Result<Object, Object> get(@Connection MyConnection connection,
                                                @MetadataKeyId(EntityKeysResolver.class) String entityKind){

    if ("Book_id".equals(entityKind)){
      Book book = (Book)connection.getClient().fetch(entityKind);
      return Result.<Object, Object>builder()
                   .output(book.content())
                   .attributes(book.attributes())
                   .build();
    }

    return return Result.<Object, Object>builder()
                 .output(connection.getClient().fetch(entityKind))
                 .build();
  }

}
```

ソースには、ペイロードで使用したのと同じような宣言がありますが、​`attributesResolver`​ 参照が追加されています。

```java
@MetadataScope(keysResolver = EntityKeysResolver.class,
               outputResolver = OutputEntityResolver.class,
               attributesResolver = OutputEntityResolver.class)
public class ListenerSource extends Source<Map<String, Object>, Object>  {

  @MetadataKeyId
  @Parameter
  public String type;

  //...

}
```

## [](#ユーザー定義の-metadatakey-を持つ出力メタデータ)ユーザー定義の MetadataKey を持つ出力メタデータ

ユーザー定義の MetadataKey のケースは、コンポーネントの出力にも適用されます。 クエリの場合は、解決される可能性のある MetadataKey のセットを事前に定義することができません。その代わりに、出力の型または構造を特徴付けるパラメーターとその値があります。

たとえば、Database Connector には ​`select`​ 操作があります。その出力は、クエリ対象のエンティティによって異なります。

```java
  @OutputResolver(output = SelectMetadataResolver.class)
  public List<Map<String, Object>> select(@MetadataKeyId String sql, @Config DbConnector connector){
    // ...
  }
```

`SelectMetadataResolver`​ は次のように宣言されています。

```java
public class SelectMetadataResolver extends BaseDbMetadataResolver implements OutputTypeResolver<String> {

  @Override
  public String getCategoryName() {
    return "DbCategory";
  }

  @Override
  public String getResolverName() {
    return "SelectResolver";
  }

  @Override
  public MetadataType getOutputType(MetadataContext context, String query)
      throws MetadataResolvingException, ConnectionException {

    if (isEmpty(query)) {
      throw new MetadataResolvingException("No Metadata available for an empty query", FailureCode.INVALID_METADATA_KEY);
    }

    ResultSetMetaData statementMetaData = getStatementMetadata(context, parseQuery(query));
    if (statementMetaData == null) {
      throw new MetadataResolvingException(format("Driver did not return metadata for the provided SQL: [%s]", query),
                                           FailureCode.INVALID_METADATA_KEY);
    }

    ObjectTypeBuilder record = context.getTypeBuilder().objectType();

    Map<String, MetadataType> recordModels = resolveRecordModels(statementMetaData);
    recordModels.entrySet()
                .forEach(e -> record.addField().key(e.getKey()).value(e.getValue()));

    return record.build();
  }
}
```

## [](#メタデータの自動ラップのリスト)メタデータの自動ラップのリスト

`select`​ の例では、操作から ​`List<Map<String, Object>`​ が返されています。SELECT クエリの結果は複数のレコードエントリであるため当然ですが、​`SelectMetadataResolver`​ は ​`getOutputType`​ メソッドで ArrayType を記述していません。その代わりに、返された MetadataType は単一の ​`record`​ 構造を表しています。

これは何故でしょうか。

すでにお分かりかも知れませんが、操作は ArrayType (リスト、PagingProvider など) を返すため、配列の ​`generic`​ 型のみを記述するだけで済みます。OutputTypeResolver と AttributesTypeResolver は常に、​_コレクション_​型自身ではなく​_コレクションの要素_​の MetadataType を解決します。これにより、MetadataType リゾルバーの再利用性が高まり、必要なコードを減らすことができます。

解決された属性は、操作の ​`List`​ 出力の属性​_ではなく_​、コレクションの​_要素_​の属性​_でもある_​ことを考慮してください。

## [](#metadatakey-を使用しない動的出力メタデータの解決)MetadataKey を使用しない動的出力メタデータの解決

入力と同様、コンポーネントの設定または接続に依存する動的型として、操作の出力は特定の ​`MetadataKey`​ がなくても解決できます。この場合も、キーレスリゾルバーを宣言するには、​`MetadataKeyId`​ パラメーターを省略して、TypeResolvers の MetadataKey を無視してください。

```java
public class UserTypeResolver implements OutputTypeResolver, AttributesTypeResolver  {

  @Override
  public String getCategoryName() {
    return "User";
  }

  @Override
  public MetadataType getOutputType(MetadataContext context, Object key)
      throws MetadataResolvingException, ConnectionException {

    // The `key` parameter will be `null` if the fetch is performed
    // as a `KeyLess` Metadata resolution. We'll just ignore it.
    String schema = getUserSchema(context);
    return new JsonTypeLoader(schema).load("http://demo.user")
            .orElseThrow(() -> new MetadataResolvingException("No Metadata is available for the User",
                                                              FailureCode.NO_DYNAMIC_TYPE_AVAILABLE));
  }

  @Override
  public MetadataType getAttributesType(MetadataContext context, Object key)
      throws MetadataResolvingException, ConnectionException {

    // The `key` parameter will be `null` if the fetch is performed
    // as a `KeyLess` Metadata resolution. We'll just ignore it.
    String schema = getUserSchema(context);
    return new JsonTypeLoader(schema).load("http://demo.attributes")
            .orElseThrow(() -> new MetadataResolvingException("No Metadata is available for the User Attributes",
                                                              FailureCode.NO_DYNAMIC_TYPE_AVAILABLE));
  }

  private String getUserSchema(MetadataContext context) throws MetadataResolvingException, ConnectionException {
    return context.<DemoConnection>getConnection()
      .orElseThrow(() -> new MetadataResolvingException("A connection is required to resolve Metadata but none was provided",
                                                        FailureCode.INVALID_CONFIGURATION))
      .describeUser();
  }
}
```

```java
public class UserOperations {

  @OutputResolver(output = UserTypeResolver.class, attributes=UserTypeResolver.class)
  public Result<Map<String,Object>, Object> getUser(@Connection DemoConnection connection){
    User user = connection.getUser();

    return Result.<Map<String,Object>, Object>.builder()
                 .output(user.personalInfo())
                 .attributes(user.accountInfo())
                 .build().

  }

}
```