// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

= Ignite REST API

The Apache Ignite 3 clusters provide an link:https://www.openapis.org/[OpenAPI] specification that can be used to work with Ignite 3 by standard REST methods. The link:https://github.com/apache/ignite-3/tree/main/modules/rest-api/openapi/openapi.yaml[openapi.yaml,window=_blank] specification file for the version is included with its release.

We recommend that you generate client code in your project language by using an link:https://github.com/OpenAPITools/openapi-generator[OpenAPI code generator,window=_blank]. Below is the example of how you can do this for a Java project.

== Example Java Project Configuration

1. Add an link:https://github.com/OpenAPITools/openapi-generator/tree/master/modules/openapi-generator-maven-plugin[open api generator,window=_blank] maven plugin to your project's pom.xml.
+
[source,xml]
----
<plugin>
  <groupId>org.openapitools</groupId>
  <artifactId>openapi-generator-maven-plugin</artifactId>
  <version>${maven.openapi.plugin.version}</version>
  <executions>
    <execution>
      <goals>
        <goal>generate</goal>
      </goals>
      <configuration>
        <inputSpec>https://github.com/apache/ignite-3/tree/main/modules/rest-api/openapi/openapi.yaml</inputSpec>
        <generatorName>java</generatorName>
        <apiPackage>org.apache.ignite.rest.client.api</apiPackage>
        <invokerPackage>org.apache.ignite.rest.client.invoker</invokerPackage>
        <modelPackage>org.apache.ignite.rest.client.model</modelPackage>
        <generateModelTests>false</generateModelTests>
        <generateApiTests>false</generateApiTests>
        <languageSpecificPrimitives>true</languageSpecificPrimitives>
        <configOptions>
          <openApiNullable>false</openApiNullable>
          <supportStreaming>false</supportStreaming>
        </configOptions>
        <library>okhttp-gson</library>
      </configuration>
    </execution>
  </executions>
</plugin>
----
+
2. Get cluster configuration from your project.
+
[source,java]
----
ApiClient client = Configuration.getDefaultApiClient();
// Set base URL
client.setBasePath("http://localhost:10300");

// Get cluster configuration.
clusterConfigurationApi = new ClusterConfigurationApi(client);
String configuration = clusterConfigurationApi.getClusterConfiguration();
----
