TIBCO EBX® は、REST Toolkit を使用してカスタム REST サービスを開発する可能性を提供します。REST Toolkit は、JAX-RS 2.1 (JSON-370) および JSON-B (JSON-367) をサポートします。
REST サービスは Java クラスによって実装され、その操作は Java メソッドによって実装されます。応答は、POJO オブジェクトをシリアル化することで生成できます。リクエスト入力は、POJO にシリアル化解除できます。JSON を含むさまざまな入力および出力形式がサポートされています。サポートされている形式の詳細については、メディアタイプを参照してください。
REST Toolkit は以下をサポートします。
注入可能なオブジェクト
EBX® は、リクエストのユーザーの認証、EBX® リポジトリへのアクセス、または構成を気にせずに URI (リバースプロキシモードや REST フォワードモードなど) を構築するために役立つ注入可能なオブジェクトを提供します。
JAX-RS 注入可能オブジェクトもサポートされています。
アノテーション
EBX® は、リソースを説明したり、匿名アクセスを許可したり、メソッドに制限を追加したりするためのアノテーションを提供します。
JAX-RS および JSON-B アノテーションもサポートされています。
ロギングおよびデバッグユーティリティ。
カスタム REST サービスを含む EBX® モジュールは、少なくとも 1 つの REST Toolkit アプリケーションクラスを提供する必要があります。REST Toolkit アプリケーションクラスは、EBX® RESTApplicationAbstract@ApplicationPath アノテーションと REST サービスクラスをスキャンするパッケージのセットを使用して、ベース URL を定義することです。
スキャンできるのは、Web アプリケーションのクラスローダーからアクセスできるパッケージのみです。
ApplicationConfigurator.register(java.lang.Class) または ApplicationConfigurator.register(java.lang.Object) を介して、Web アプリケーションアーカイブの内部または外部にパッケージ化された REST リソースクラスまたはシングルトンを登録できます。
パッケージスコープが定義されていない場合、Web アプリケーションのクラスローダーから到達可能なすべてのクラスがスキャンされます。
アプリケーションパスを「/」にすることはできません。また、モジュールの既存のリソースと競合することはできません。「/rest」 (RESTApplicationAbstract.REST_DEFAULT_APPLICATION_PATH 定数の値) を使用することをお勧めします。
EBX® ドキュメント
import javax.ws.rs.*;
import com.orchestranetworks.rest.*;
import com.orchestranetworks.rest.annotation.*;
@ApplicationPath(RESTApplicationAbstract.REST_DEFAULT_APPLICATION_PATH)
@Documentation("My REST sample application")
public final class RESTApplication extends RESTApplicationAbstract
{
   public RESTApplication()
   {
      // Adds one or more package names which will be used to scan for components.
      super((cfg) -> cfg.addPackages(RESTApplication.class.getPackage()));
   }
}
REST Toolkit サービスは Java クラスによって実装され、その操作はそのメソッドによって実装されます。
クラスとメソッドに @Path アノテーションを付けて、アクセスパスを指定できます。クラスレベルで定義された @Path アノテーション値は、メソッドで定義された値の前に追加されます。警告:クラスまたはメソッドごとに許可される @Path アノテーションは 1 つだけです。
リソースによって受け入れられ、生成されるメディアタイプは、それぞれ @Consumes および @Produces JAX-RS アノテーションによって定義されます。サポートされているメディアタイプは次のとおりです。
application/json (  MediaType.APPLICATION_JSON_TYPE  )
application/octet-stream (  MediaType.APPLICATION_OCTET_STREAM_TYPE  )
application/x-www-form-urlencoded (  MediaType.APPLICATION_FORM_URLENCODED_TYPE  )
multipart/form-data (  MediaType.MULTIPART_FORM_DATA_TYPE  )
text/css
text/html (  MediaType.TEXT_HTML_TYPE  )
text/plain (  MediaType.TEXT_PLAIN_TYPE  )
有効な HTTP(S) メソッドは、JAX-RS アノテーション @GET、@POST、@PUT などによって指定されます。これらのアノテーションの 1 つのみ各 Java メソッドに設定できます (これは、Java メソッドがサポートできる HTTP メソッドは 1 つだけであることを意味します)。
警告:名前の前に ebx- が付いた URL パラメーターは、REST Toolkit によって予約されており、EBX® ドキュメントで明示的に許可されていない限り、カスタム REST サービスで定義しないでください。
サンプルの記述サービスにアクセスするための REST URL は次のように定義されています。
http[s]://<host>[:<port>]/<path to webapp>/rest/track/v1/description
説明
<path to webapp> は、REST Toolkit アプリケーションを保持する Web アプリケーションのパスに対応し、それ自体がサンプルサービスを提供します。パスは、複数の URI セグメント、または Web アプリケーションの名前が続く URI セグメントで構成されます。
/rest/track/v1/description は、アプリケーションの @ApplicationPath とサービスの @Path アノテーションの連結に対応していることに注意してください。
次の REST Toolkit サービスサンプルは、トラックデータをクエリおよび管理するためのメソッドを提供します。
import java.net.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.*;
import java.util.stream.*;
import javax.servlet.http.*;
import javax.ws.rs.*;
import javax.ws.rs.container.*;
import javax.ws.rs.core.*;
import com.orchestranetworks.rest.annotation.*;
import com.orchestranetworks.rest.inject.*;
/**
 * The REST Toolkit Track service v1.
 */
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/track/v1")
@Documentation("Track service")
public final class TrackService
{
	@Context
	private ResourceInfo resourceInfo;
	@Context
	private SessionContext sessionContext;
	private static final Map<Integer, TrackDTO> TRACKS = new ConcurrentHashMap<>();
	/**
	 * Gets service description
	 */
	@GET
	@Path("/description")
	@Documentation("Gets service description")
	@Produces({ MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON })
	@AnonymousAccessEnabled
	public String handleServiceDescription()
	{
		return this.resourceInfo.getResourceMethod().getAnnotation(Documentation.class).value();
	}
	/**
	 * Selects tracks.
	 */
	@GET
	@Path("/tracks")
	@Documentation("Selects tracks")
	public Collection<TrackDTO> handleSelectTracks(
			@QueryParam("singerFilter") final String singerFilter, // a URL parameter holding a Java regular expression
			@QueryParam("titleFilter") final String titleFilter) // a URL parameter holding a Java regular expression
	{
		final Pattern singerPattern = TrackService.compilePattern(singerFilter);
		final Pattern titlePattern = TrackService.compilePattern(titleFilter);
		return TRACKS.values()
				.stream()
				.filter(Objects::nonNull)
				.filter(track -> singerPattern == null || singerPattern.matcher(track.singer).matches())
				.filter(track -> titlePattern == null || titlePattern.matcher(track.title).matches())
				.collect(Collectors.toList());
	}
	private static Pattern compilePattern(final String aPattern)
	{
		if (aPattern == null || aPattern.isEmpty())
			return null;
		try
		{
			return Pattern.compile(aPattern);
		}
		catch (final PatternSyntaxException ignore)
		{
			// ignore invalid pattern
			return null;
		}
	}
	/**
	 * Counts all tracks.
	 */
	@GET
	@Path("/tracks:count")
	@Documentation("Counts all tracks")
	public int handleCountTracks()
	{
		return TRACKS.size();
	}
	/**
	 * Selects a track by id.
	 */
	@GET
	@Path("/tracks/{id}")
	@Documentation("Selects a track by id")
	public TrackDTO handleSelectTrackById(@PathParam("id") Integer id)
	{
		final TrackDTO track = TRACKS.get(id);
		if (track == null)
			throw new NotFoundException("Track id [" + id + "] does not found.");
		return track;
	}
	/**
	 * Deletes a track by id.
	 */
	@DELETE
	@Path("/tracks/{id}")
	@Documentation("Deletes a track by id")
	public void handleDeleteTrackById(@PathParam("id") Integer id)
	{
		if (!TRACKS.containsKey(id))
			throw new NotFoundException("Track id [" + id + "] does not found.");
		TRACKS.remove(id);
	}
	/**
	 * Inserts or updates one or several tracks.
	 * <p>
	 * The complex response structure corresponds to one of:
	 * <ul>
	 *  <li>An empty content with the <code>location<code> HTTP header defined
	 *   to the access URI.</li>
	 *  <li>A JSON array of {@link ResultDetailsDTO} objects.</li>
	 * </ul>
	 */
	@POST
	@Path("/tracks")
	@Documentation("Inserts or updates one or several tracks")
	public Response handleInsertOrUpdateTracks(List<TrackDTO> tracks)
	{
		int inserted = 0;
		int updated = 0;
		final ResultDetailsDTO[] resultDetails = new ResultDetailsDTO[tracks.size()];
		int resultIndex = 0;
		final URI base = this.sessionContext.getURIInfoUtility()
				.createBuilderForRESTApplication()
				.path(this.getClass())
				.segment("tracks")
				.build();
		for (final TrackDTO track : tracks)
		{
			final String id = String.valueOf(track.id);
			final URI uri = UriBuilder.fromUri(base).segment(id).build();
			final int code;
			if (TRACKS.containsKey(track.id))
			{
				code = HttpServletResponse.SC_NO_CONTENT;
				updated++;
			}
			else
			{
				code = HttpServletResponse.SC_CREATED;
				inserted++;
			}
			TRACKS.put(track.id, track);
			resultDetails[resultIndex++] = ResultDetailsDTO.create(
				code,
				null,
				String.valueOf(track.id),
				uri);
		}
		if (inserted == 1 && updated == 0)
			return Response.created(resultDetails[0].details).build();
		return Response.ok().entity(resultDetails).build();
	}
	/**
	 * Updates one track.
	 */
	@PUT
	@Path("/tracks/{id}")
	@Documentation("Update one track")
	public void handleUpdateOneTrack(@PathParam("id") Integer id, TrackDTO aTrack)
	{
		final TrackDTO track = TRACKS.get(id);
		if (track == null)
			throw new NotFoundException("Track id [" + id + "] does not found.");
		if (aTrack.id != null && !aTrack.id.equals(track.id))
			throw new BadRequestException("Selected track id [" + id
				+ "] is not equals to body track id.");
		TRACKS.put(aTrack.id, aTrack);
	}
}
この REST サービスは、データ転送オブジェクト (DTO) を表す次の Java クラスを使用して、データをシリアル化および逆シリアル化します。
/**
 * DTO for a track.
 */
public final class TrackDTO
{
	public Integer id;
	public String singer;
	public String title;
}
import java.net.*;
/**
 * DTO for result details.
 */
@JsonbPropertyOrder({ "code", "label", "foreignKey", "details" })
public final class ResultDetailsDTO
{
	public int code;
	public String label;
	public String foreignKey;
	public URI details;
	public static ResultDetailsDTO create(
		final int aCode,
		final String aForeignKey,
		final URI aDetails)
	{
		return ResultDetailsDTO.create(aCode, null, aForeignKey, aDetails);
	}
	public static ResultDetailsDTO create(
		final int aCode,
		final String aLabel,
		final String aForeignKey,
		final URI aDetails)
	{
		final ResultDetailsDTO result = new ResultDetailsDTO();
		result.code = aCode;
		result.label = aLabel;
		result.foreignKey = aForeignKey;
		result.details = aDetails;
		return result;
	}
}
デフォルトの JSON シリアライザーとデシリアライザーは、DTO で ContentHolder として宣言されたときにテーブルレコードを処理するために提供されています。拡張とコンパクトの両方の JSON 形式のレコードがサポートされています。
/**
 * DTO for a singer.
 */
public final class SingerDTO
{
	@Table(
		dataModel = "urn:ebx:module:tracks-module:/WEB-INF/ebx/schemas/tracks.xsd",
		tablePath = "/root/Singers")
	public ContentHolder content;
}
同じ DTO をシリアル化と逆シリアル化に使用できます。シリアル化の場合、ContentHolderForInput インスタンスが自動的に作成され、適切なデータが入力されます。その後、このインスタンスはそのデータを ValueContextForUpdate にコピーできるようになります。テーブルレコードを逆シリアル化するには、ContentHolderForOutput を REST 操作 JAVA メソッドで作成し、返す必要があります。提供された Adaptation データは、JSON の有効なピースに変換され、HTTP 応答本文に配置されます。
/**
 * The REST Toolkit Singer service v1.
 */
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/singer/v1")
@Documentation("Singer service")
public final class SingerService
{
	...
	/**
	 * Selects a singer by id.
	 */
	@GET
	@Path("/singers/{id}")
	@Documentation("Selects a singer by id")
	public SingerDTO handleSelectSingerById(final @PathParam("id") Integer id)
	{
		// find the singer adaptation by id
		final Adaptation singerRecord = ... ; 
		
		final SingerDTO singerDTO = new SingerDTO();
		singerDTO.content = ContentHolderForOutput.createForRecord(singerRecord);
		return singerDTO;
	}
	/**
	 * Inserts one singer.
	 */
	@POST
	@Path("/singers")
	@Documentation("Inserts one singer")
	public void handleInsertOneSinger(final SingerDTO aSingerDTO)
	{
		final ProgrammaticService svc = ... ;
		final AdaptationTable singersTable = ... ;
		final ProcedureResult procedureResult = svc.execute(
				(aContext) -> {
					final ValueContextForUpdate createContext = aContext.getContextForNewOccurrence(singersTable); ;
					aSingerDTO.content.asContentHolderForInput().copyTo(createContext);
					aContext.doCreateOccurrence(createContext, singersTable);
				});
		if (procedureResult.hasFailed())
			throw new UnprocessableEntityException(
				procedureResult.getException().getLocalizedMessage());
	}
	
	/**
	 * updates one singer.
	 */
	@PUT
	@Path("/singers/{id}")
	@Documentation("updates one singer")
	public void handleUpdateOneSinger(@PathParam("id") final Integer id, final SingerDTO aSingerDTO)
	{
		final ProgrammaticService svc = ... ;
		final AdaptationTable singersTable = ... ;
		final ProcedureResult procedureResult = svc.execute(
				(aContext) -> {
					// find the singer adaptation by id
					final Adaptation singerRecord = ... ;
					if (singerRecord == null)
						throw new NotFoundException("Singer with the id ["+ id + "] has not been found.");
					final ValueContextForUpdate createContext = aContext.getContext(singerRecord.getAdaptationName()); ;
					aSingerDTO.content.asContentHolderForInput().copyTo(createContext);
					aContext.doModifyContent(singerRecord, createContext);
				});
		if (procedureResult.hasFailed()){
			final Exception ex = procedureResult.getException();
			final Throwable cause = ex.getCause();
			if(cause instanceof NotFoundException)
				throw (NotFoundException) cause;
			throw new UnprocessableEntityException(ex.getLocalizedMessage());
		}	
	}
}
応答のデフォルトの JSON 形式は、ビジネスデータフィールドのみで構成され、コンパクトと呼ばれます。
{
  "singer":{
  	"firstname":"Frank",
  	"lastname":"Sinatra"
  }
}
技術フィールドまたはメタデータを追加するには、ExtendedOutput アノテーションを ContentHolder フィールドの上に配置する必要があります。アノテーションは、必要なすべてのオプションまたは ALL オプションを宣言する必要があります。
/**
 * DTO for a singer with technical fields.
 */
public final class SingerWithTechnicalsDTO
{
	@Table(
		dataModel = "urn:ebx:module:tracks-module:/WEB-INF/ebx/schemas/tracks.xsd",
		tablePath = "/root/Singers")
	@ExtendedOutput({Include.LABEL,Include.TECHNICALS,Include.CONTENT})
	public ContentHolder content;
}
{
  "singer":{
   	"label": "23",
   	"creationDate": "2018-09-04T15:35:10.706",
    "creationUser": "user",
    "lastUpdateDate": "2018-10-02T17:05:47.090",
    "lastUpdateUser": "user",
  	"content":{
  		"firstname":{
  			"content":"Frank",
  			"label":"First Name"
  		},
  		"lastname":{
  			"content":"Sinatra",
  			"label":"Last Name"
  		}
 	  }
  }
}
入力 HTTP リクエストに拡張 JSON 形式を使用するには、ExtendedInput アノテーションを ContentHolder フィールドの上に配置する必要があります。
/**
 * DTO for a singer using the extended JSON format.
 */
public final class SingerExtendedInputDTO
{
	@Table(
		dataModel = "urn:ebx:module:tracks-module:/WEB-INF/ebx/schemas/tracks.xsd",
		tablePath = "/root/Singers")
	@ExtendedInput
	public ContentHolder content;
}
TIBCO EBX® は JSON-B (JSON-367) に基づいているため、カスタムシリアライザーとデシリアライザーは JsonbTypeSerializer および JsonbTypeDeserializer アノテーションを使用して定義できます。
デフォルトでは、java.math.BigDecimal は JSON String にシリアル化されます。この動作をオーバーライドするには、カスタムシリアライザーを JSON Number に実装します。
/**
 * Serializes decimal values in numbers.
 */
public final class BigDecimalSerializerInJsonNumber implements JsonbSerializer<BigDecimal>
{
	@Override
	public void serialize(
		final BigDecimal aBigDecimal,
		final JsonGenerator aJsonGenerator,
		final SerializationContext aSerializationContext)
	{
		if (aBigDecimal == null)
			aJsonGenerator.writeNull();
		else
			aJsonGenerator.write(aBigDecimal);
	}
}
/**
 * DTO for a vynil.
 */
public final class VinylDTO
{
	@JsonbTypeSerializer(BigDecimalSerializerInJsonNumber.class)
	public BigDecimal price;
	@JsonbTypeSerializer(CustomTrackDtoSerializer.class)
	@JsonbTypeDeserializer(CustomTrackDtoDeserializer.class)
	public TrackDTO track;
}
REST Toolkit で開発されたカスタム REST サービスは、ビルトインの REST データサービスと同じ認証方法とルックアップメカニズムをサポートします。ただし、「匿名認証スキーム」については、AnonymousAccessEnabled
デフォルトでは、すべての REST リソース Java メソッドでユーザーを認証する必要があります。
ただし、一部のメソッドは匿名でアクセスできる必要がある場合があります。これらのメソッドには、AnonymousAccessEnabled
一部のメソッドは、特定のプロファイルに制限する必要がある場合があります。これらのメソッドには、認証ルールを指定するために AuthorizationAuthorizationRule
import javax.ws.rs.*;
import com.orchestranetworks.rest.annotation.*;
/**
 * The REST Toolkit service v1.
 */
@Path("/service/v1")
@Documentation("Service")
public final class Service
{
	...
	/**
	 * Gets service description
	 */
	@GET
	@AnonymousAccessEnabled
	public String handleServiceDescription()
	{
		...
	}
	/**
	 * Gets restricted service
	 */
	@GET
	@Authorization(IsUserAuthorized.class)
	public RestrictedServiceDTO handleRestrictedService()
	{
		...
	}
}
REST Toolkit は、URI を生成するためのユーティリティインターフェイス URIInfoUtilitySessionContext
いくつかの URI ビルダーインターフェイスは、ビルトイン RESTful サービスの URI ビルドを容易にするように設計されています。各インターフェイスは、同じ機能概念に関連するメソッドの集合体を構成します。この分割により、モジュール式および汎用アルゴリズムの開発が可能になります。これらのインターフェイスの一部は、それ自体が他のインターフェイスの集合体であり、メソッド呼び出しの一貫した組み合わせのみが許可されているため、ビルダーを直感的に使用できます。たとえば、REST 階層カテゴリ用に構成された URI ビルダーは、レコードアクセスが REST データカテゴリの概念の一部であるため、レコード URI ビルドメソッドの呼び出しを許可しません。
さらに、これらの URI ビルダーは、次のように事前構成されています。
基本構成を構成する着信 HTTP リクエストからのデータ。
EBX® モジュールセグメントの前に追加されるモジュールのパブリックパスプレフィックス (存在する場合)。
データサービスリネージ設定は、以前の構成全体をオーバーライドします (存在する場合)。
REST フォワードモードは、URI のパスのピースのみがアクティブ化されている場合に保持されるため、以前の構成を部分的にオーバーライドします。
詳細については、URIBuilderForBuiltinCategoryURIBuilder
リソースアクセス URI を生成する URI ビルダーも利用できます。リソースは 1 つの機能概念としてのみ見なされるため、すべてのメソッドは同じインターフェイスで定義されています。
ビルトインデータサービスの URI ビルダーと同様に、これらのサービスは次のように事前構成されています。
基本構成を構成する着信 HTTP リクエストからのデータ。
外部リソース設定は、以前の構成のすべてまたは一部をオーバーライドします (存在する場合)。
EBX® モジュールセグメントが存在する場合はその先頭に追加するモジュールのパブリックパスプレフィックス。
以前のビルダーでカバーされていないサービスまたはリソースへの URI をビルドする必要がある場合は、デフォルトの事前構成済み URI ビルダーを使用する必要があります。終了パスセグメントのみが異なる 2 つのデフォルト URI ビルダーがあります。最初のパスはサーバーのセグメント (EBX® モジュールセグメントの直前) で終了し、2 番目のパスは REST アプリケーションの最後のセグメント (@ApplicationPath アノテーションで定義) で終了します。
これらのデフォルトの URI ビルダーは、次のように事前構成されています。
基本構成を構成する着信 HTTP リクエストからのデータ。
EBX® モジュールセグメントが存在する場合はその先頭に追加するモジュールのパブリックパスプレフィックス。
REST Toolkit Javaメソッドは、JAX-RS クラス javax.ws.rs.WebApplicationException を拡張する Java 例外をスローすることにより、標準の HTTP エラー応答を生成できます。JAX-RS は、さまざまな HTTP ステータスコードの例外を定義します。EBX® は、HTTP 422 (処理不能エンティティ) コードのサポートを追加する UnprocessableEntityException
プレーン Java 例外は、HTTP ステータスコード 500 (内部サーバーエラー) にマップされます。
{
  "code": 999,                      // JSON Number, HTTP error code or EBX® error code
                                    // in case of HTTP error 422 (optional)
  "errors": [                       // Additional messages to give details (optional).
    {
      "message": "Message 1"        // JSON String
    },
    {
      "message": "Message 2"
    }
  ]
}
REST Toolkit イベントの監視は、データサービスのログ構成に似ています。違いは、ebx.log4j.category.log.restServices にする必要があるプロパティキーです。
ログメッセージを構成するために、いくつかの追加のプロパティを使用できます。詳細については、REST Toolkit サービスの構成を参照してください。
すべてのアプリケーションとコンポーネントは、モジュールの Web アプリケーション (warファイル) にパッケージ化する必要があります。
JAX-RS クライアント API を除く JAX-RS ライブラリは、すでに ebx.jar に含まれているため、war ファイルにパッケージ化しないでください。
詳細については、Java EE 展開を参照してください。
REST Toolkit アプリケーションの登録は、EBX® モジュール登録プロセスに統合されています。登録クラスは ModuleRegistrationListener@WebListener を宣言し、handleContextInitialized メソッドをオーバーライドする必要があります。
詳細については、モジュール登録を参照してください。
import javax.servlet.annotation.*;
import com.orchestranetworks.module.*;
@WebListener
public final class RegistrationModule extends ModuleRegistrationListener
{
	@Override
	public void handleContextInitialized(final ModuleInitializedContext aContext)
	{
		// Registers dynamically a REST Toolkit application.
		aContext.registerRESTApplication(RESTApplication.class);
	}
}
TIBCO EBX® ネイティブ統合によって生成された OpenAPI ドキュメントは、OpenAPI V3 仕様に準拠しています。REST Toolkit アプリケーションの利用可能な REST リソースと関連する操作を構造化して記述することにより、これらのドキュメントは、その開発と消費を容易にします。ただし、現在サポートされているのは、JSON 形式のみです。
OpenAPI ドキュメントの生成を有効にするには、次のことが必要です。
REST Toolkit アプリケーションクラスで、OpenApiApplicationPath
OpenAPI アプリケーションパスの後には、ジェネレーターバージョンが続きます (/{open-api-application-path}/v1)。ジェネレーターのバージョンと open-api の仕様のバージョンが混同されるため、/open-api のようなパスを使用しないことが推奨されます。
ドキュメント作成時に考慮すべきは、REST Toolkit のクラスリソースに OpenApiResource
パラメーター ebx.restservices.openApi.unpublished.applications を使用して、特定の環境で OpenAPI エンドポイントを公開しないようにすることができます。
################################################################ # Comma-separated list of canonical application class names # whose OpenAPI descriptions will not be published. ################################################################ ebx.restservices.openApi.unpublished.applications=com.example.RestApplication
パラメーター ebx.restservices.openapi.style.short.name を使用して、生成されたスキーマの名前を簡略化できます。
################################################################ # If true, only the simple name of the DTO classes will be used to name the OpenAPI schemas. # It also removes the DTO and Dto suffixes at the end of the class name. # Default value is false. # Note that this may cause conflicts between DTOs with the same name under different packages. # It is not recommended, when set to true, to use the underscore character '_' in @Schema # annotations since it cause calculation errors. ################################################################ ebx.restservices.openapi.style.short.name=true
OpenAPI 操作は、GET または POST HTTP メソッドを使用して、アプリケーション全体または単一のサービスの JSON ドキュメントを生成します。
アプリケーションの URL フォーマットは次のとおりです。
http[s]://<host>[:<port>]/<open-api-path>/v1
1 つのサービスの URL フォーマットは次のとおりです。
http[s]://<host>[:<port>]/<open-api-application-path>/v1/{resourcePath: [^:]*}
説明
<open-api-application-path> は、OpenApiApplicationPath
{resourcePath: [^:]*} は、ドキュメントへの REST リソースのパスに対応します。
| HTTP コード | 説明 | 
|---|---|
| 
 | ドキュメントは正常に生成されました。 | 
| 
 | 認証に失敗しました。 | 
| 
 | 指定されたリソースの読み取り権限は、現在のユーザーに対して拒否されました。 | 
| 
 | URL で指定されたリソースが見つかりません。 | 
OpenAPI ドキュメントを生成するためにデフォルトで処理される JAX-RS アノテーションに加え、TIBCO EBX® は Microprofile OpenAPI アノテーションをサポートしています。これらのアノテーションは、REST Toolkit フレームワークによってすでにカバーされている OpenAPI ドキュメントの部分を書き換える必要なく、記述を強化するために使用されます。アノテーションは、そのタイプに応じて、アプリケーションとリソースクラスの両方で使用することができます。
リソースクラスで明示的に定義されていない場合、OpenAPIDefinition アノテーションは、その REST Toolkit アプリケーションクラスから継承されます。このアノテーションは、OpenAPI ドキュメントのルートドキュメントオブジェクトを記述しています。
ContentHolder
フィールドに Table アノテーションが設定されている必要があります。
Schema アノテーションは、処理のためにフィールドにタグ付けする必要があります。
Schema アノテーションの ref 値を空にすることはできず、アプリケーションスコープ全体で一意にする必要があります。
/**
 * DTO for a singer.
 */
public final class SingerDTO
{
	@Table(
			dataModel = "urn:ebx:module:tracks-module:/WEB-INF/ebx/schemas/tracks.xsd",
			tablePath = "/root/Singers")
	@Schema(ref = "singer")
	public ContentHolder content;
}
制限により、この場合、メタデータフィールドは追加されないことに注意してください。
開発実行モードでは、OpenAPI エンドポイントへの匿名アクセスがすべてのユーザーに許可されます。実稼働および統合実行モードでは、OpenAPI アクセス権限は 基礎となるリソースのものから継承されます。
リソースのドキュメントには、現在のユーザーがアクセスできる操作のみが含まれます。
現在のユーザーが操作にアクセスできない場合は、権限が拒否されたことが返されます。
REST Toolkit アプリケーションのドキュメントには、許可されたリソースのスコープのみが含まれます。
現在のユーザーがどのリソースにもアクセスできない場合は、権限が拒否されたことが返されます。
開発実行モードでは、Swagger UI は [UI] タブの [管理] > [技術構成] > [モジュールおよびデータモデル] から利用できます。これにより、対応する REST Toolkit アプリケーションの文書化されたリソースを表示および操作できます。ビジュアルドキュメントにより、バックエンドの実装とクライアント側での使用が容易になります。
Swagger UI は、次の URL から直接利用することもできます。
アプリケーションの OpenAPI 視覚化の URL フォーマット
http[s]://<host>[:<port>]/<open-api-application-path>/v1/ui
単一サービスの OpenAPI 視覚化の URL フォーマット
http[s]://<host>[:<port>]/<open-api-application-path>/v1/ui/{resourcePath: [^:]*}
説明
<open-api-application-path> は、OpenApiApplicationPath
{resourcePath: [^:]*} は、ドキュメントへの REST リソースのパスに対応します。
リバースプロキシまたは HTTPS 構成を使用する場合、OpenAPI UI は外部リソースと見なされます。つまり、外部リソース URL を正しく構成する必要があります。
| OpenAPI | テーブルレコードのシリアル化では、メタデータフィールドは追加されません。 詳細については、テーブルレコードのシリアル化を参照してください。 リストまたはマップではない Java ジェネリックを使用する DTO クラスはサポートされていません。 |