Improve API documentation

This commit is contained in:
sureshms 2021-08-02 14:21:59 -07:00
parent 62d5d88502
commit 5ca728e8f8
24 changed files with 174 additions and 80 deletions

View File

@ -337,24 +337,19 @@
</server>
</servers>
<info>
<title>Open Metadata Apis</title>
<version>1.0.0</version>
<termsOfService>Terms</termsOfService>
<title>OpenMetadata Apis</title>
<version>0.3.0</version>
<contact>
<email>e@mail.com</email>
<name>Open Metadata</name>
<url>https:/open-metadata.io</url>
<email>contact@open-metadata.org</email>
<name>OpenMetadata</name>
<url>https:/open-metadata.org</url>
</contact>
<license>
<url>https://license</url>
<name>MIT</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
<name>Apache 2.0</name>
</license>
<extensions>
<x-custom-field-1>my-custom-field-1</x-custom-field-1>
<x-custom-field-2>my-custom-field-2</x-custom-field-2>
</extensions>
</info>
<descriptionFile>src/test/resources/descriptions.md</descriptionFile>
<descriptionFile>../docs/openmetadata-apis/apis.md</descriptionFile>
</swaggerConfig>
</configuration>
<executions>

View File

@ -95,8 +95,8 @@ public abstract class DashboardRepository {
return setFields(EntityUtil.validate(id, dashboardDAO().findById(id), Dashboard.class), fields);
}
public List<Dashboard> list(Fields fields, String fqn) throws IOException {
List<String> jsonList = dashboardDAO().list(fqn);
public List<Dashboard> list(Fields fields) throws IOException {
List<String> jsonList = dashboardDAO().list();
List<Dashboard> dashboardList = new ArrayList<>();
for (String json : jsonList) {
dashboardList.add(setFields(JsonUtils.readValue(json, Dashboard.class), fields));
@ -171,7 +171,7 @@ public abstract class DashboardRepository {
@SqlQuery("SELECT json FROM dashboard_entity WHERE fullyQualifiedName = :name")
String findByFQN(@Bind("name") String name);
@SqlQuery("SELECT json FROM dashboard_entity WHERE (fullyQualifiedName = :name OR :name is NULL)")
List<String> list(@Bind("name") String name);
@SqlQuery("SELECT json FROM dashboard_entity")
List<String> list();
}
}

View File

@ -94,8 +94,8 @@ public abstract class MetricsRepository {
}
@Transaction
public List<Metrics> list(Fields fields, String fqn) throws IOException {
List<String> jsonList = metricsDAO().list(fqn);
public List<Metrics> list(Fields fields) throws IOException {
List<String> jsonList = metricsDAO().list();
List<Metrics> metricsList = new ArrayList<>();
for (String json : jsonList) {
metricsList.add(setFields(JsonUtils.readValue(json, Metrics.class), fields));
@ -168,8 +168,8 @@ public abstract class MetricsRepository {
@SqlQuery("SELECT json FROM metric_entity WHERE fullyQualifiedName = :name")
String findByFQN(@Bind("name") String name);
@SqlQuery("SELECT json FROM metric_entity WHERE (fullyQualifiedName = :name OR :name is NULL)")
List<String> list(@Bind("name") String name);
@SqlQuery("SELECT json FROM metric_entity")
List<String> list();
@SqlQuery("SELECT EXISTS (SELECT * FROM metric_entity where id = :id)")
boolean exists(@Bind("id") String id);

View File

@ -94,8 +94,8 @@ public abstract class ReportRepository {
return setFields(EntityUtil.validate(id, reportDAO().findById(id), Report.class), fields);
}
public List<Report> list(Fields fields, String fqn) throws IOException {
List<String> jsonList = reportDAO().list(fqn);
public List<Report> list(Fields fields) throws IOException {
List<String> jsonList = reportDAO().list();
List<Report> reportList = new ArrayList<>();
for (String json : jsonList) {
reportList.add(setFields(JsonUtils.readValue(json, Report.class), fields));
@ -168,8 +168,8 @@ public abstract class ReportRepository {
@SqlQuery("SELECT json FROM report_entity WHERE fullyQualifiedName = :name")
String findByFQN(@Bind("name") String name);
@SqlQuery("SELECT json FROM report_entity WHERE (name = :name OR :name is NULL)")
List<String> list(@Bind("name") String name);
@SqlQuery("SELECT json FROM report_entity")
List<String> list();
@SqlQuery("SELECT EXISTS (SELECT * FROM report_entity where id = :id)")
boolean exists(@Bind("id") String id);

View File

@ -17,6 +17,7 @@
package org.openmetadata.catalog.resources;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.openmetadata.catalog.resources.databases.TableResource.TableList;
import org.openmetadata.catalog.type.CollectionDescriptor;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
@ -25,6 +26,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.openmetadata.catalog.util.ResultList;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@ -37,6 +39,7 @@ import java.util.List;
@Path("/v1")
@Api(value = "All collections in the catalog application", tags = "All collections in the Catalog")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Collection(name = "root")
public class CatalogResource {
public static class CollectionList extends ResultList<CollectionDescriptor> {
@ -59,7 +62,9 @@ public class CatalogResource {
}
@GET
@Operation(summary = "List all collections", tags = "",
@Operation(summary = "List all collections", tags = "general",
description = "List all the collections supported by OpenMetadata. This list provides all the collections " +
"and resource REST endpoints.",
responses = {
@ApiResponse(responseCode = "200", description = "All collections",
content = @Content(mediaType = "application/json",

View File

@ -86,6 +86,7 @@ public class BotsResource {
@GET
@Operation(summary = "List bots", tags = "bots",
description = "Get a list of bots.",
responses = {
@ApiResponse(responseCode = "200", description = "List of bots",
content = @Content(mediaType = "application/json", schema = @Schema(implementation =
@ -100,7 +101,8 @@ public class BotsResource {
@GET
@Path("/{id}")
@Operation(summary = "Get a bot by ID", tags = "bots",
@Operation(summary = "Get a bot", tags = "bots",
description = "Get a bot by `id`.",
responses = {
@ApiResponse(responseCode = "200", description = "The bot",
content = @Content(mediaType = "application/json", schema = @Schema(implementation =
@ -115,6 +117,7 @@ public class BotsResource {
@POST
@Operation(summary = "Create a bot", tags = "bots",
description = "Create a new bot.",
responses = {
@ApiResponse(responseCode = "200", description = "The bot ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation =

View File

@ -18,8 +18,13 @@ package org.openmetadata.catalog.resources.config;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.openmetadata.catalog.CatalogApplicationConfig;
import org.openmetadata.catalog.resources.Collection;
import org.openmetadata.catalog.security.AuthenticationConfiguration;
import org.openmetadata.catalog.type.CollectionDescriptor;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@ -32,6 +37,7 @@ import javax.ws.rs.core.UriInfo;
@Path("/v1/config")
@Api(value = "Get configuration")
@Produces(MediaType.APPLICATION_JSON)
@Collection(name = "config")
public class ConfigResource {
private final CatalogApplicationConfig catalogApplicationConfig;
@ -42,7 +48,12 @@ public class ConfigResource {
@GET
@Path(("/auth"))
@Operation(summary = "Get auth configuration")
@Operation(summary = "Get auth configuration", tags = "general",
responses = {
@ApiResponse(responseCode = "200", description = "Auth configuration",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = AuthenticationConfiguration.class)))
})
public AuthenticationConfiguration getAuthConfig(@Context UriInfo uriInfo, @Context SecurityContext securityContext) {
AuthenticationConfiguration authenticationConfiguration = new AuthenticationConfiguration();
if (catalogApplicationConfig.getAuthenticationConfiguration() != null) {

View File

@ -97,6 +97,7 @@ public class DashboardResource {
.split(","));
@GET
@Operation(summary = "List dashboards", tags = "dashboards",
description = "Get a list of dashboards. Use `fields` parameter to get only necessary fields.",
responses = {
@ApiResponse(responseCode = "200", description = "List of dashboards",
content = @Content(mediaType = "application/json",
@ -106,17 +107,15 @@ public class DashboardResource {
@Context SecurityContext securityContext,
@Parameter(description = "Fields requested in the returned resource",
schema = @Schema(type = "string", example = FIELDS))
@QueryParam("fields") String fieldsParam,
@Parameter(description = "Get dashboards that match fullyQualifiedName",
schema = @Schema(type = "string", example = "snowflakeWestCoast.finances"))
@QueryParam("fqn") String fqn) throws IOException {
@QueryParam("fields") String fieldsParam) throws IOException {
Fields fields = new Fields(FIELD_LIST, fieldsParam);
return new DashboardList(addHref(uriInfo, dao.list(fields, fqn)));
return new DashboardList(addHref(uriInfo, dao.list(fields)));
}
@GET
@Path("/{id}")
@Operation(summary = "Get a dashboard", tags = "dashboards",
description = "Get a dashboard by `id`.",
responses = {
@ApiResponse(responseCode = "200", description = "The dashboard",
content = @Content(mediaType = "application/json",
@ -135,6 +134,7 @@ public class DashboardResource {
@POST
@Operation(summary = "Create a dashboard", tags = "dashboards",
description = "Create a new dashboard.",
responses = {
@ApiResponse(responseCode = "200", description = "The dashboard",
content = @Content(mediaType = "application/json",
@ -151,6 +151,7 @@ public class DashboardResource {
@PUT
@Operation(summary = "Create or update a dashboard", tags = "dashboards",
description = "Create a new dashboard, if it does not exist or update an existing dashboard.",
responses = {
@ApiResponse(responseCode = "200", description = "The dashboard",
content = @Content(mediaType = "application/json",

View File

@ -126,6 +126,9 @@ public class DatabaseResource {
@GET
@Valid
@Operation(summary = "List databases", tags = "databases",
description = "Get a list of databases, optionally filtered by `service` it belongs to. Use `fields` " +
"parameter to get only necessary fields. Use cursor-based pagination to limit the number " +
"entries in the list using `limit` and `before` or `after` query params.",
responses = {
@ApiResponse(responseCode = "200", description = "List of databases",
content = @Content(mediaType = "application/json",
@ -183,6 +186,7 @@ public class DatabaseResource {
@GET
@Path("/{id}")
@Operation(summary = "Get a database", tags = "databases",
description = "Get a database by `id`.",
responses = {
@ApiResponse(responseCode = "200", description = "The database",
content = @Content(mediaType = "application/json",
@ -202,7 +206,8 @@ public class DatabaseResource {
@GET
@Path("/name/{fqn}")
@Operation(summary = "Get a database by fully qualified name", tags = "databases",
@Operation(summary = "Get a database by name", tags = "databases",
description = "Get a database by fully qualified name.",
responses = {
@ApiResponse(responseCode = "200", description = "The database",
content = @Content(mediaType = "application/json",
@ -222,6 +227,7 @@ public class DatabaseResource {
@POST
@Operation(summary = "Create a database", tags = "databases",
description = "Create a database under an existing `service`.",
responses = {
@ApiResponse(responseCode = "200", description = "The database",
content = @Content(mediaType = "application/json",
@ -240,6 +246,7 @@ public class DatabaseResource {
@PATCH
@Path("/{id}")
@Operation(summary = "Update a database", tags = "databases",
description = "Update an existing database using JsonPatch.",
externalDocs = @ExternalDocumentation(description = "JsonPatch RFC",
url = "https://tools.ietf.org/html/rfc6902"))
@Consumes(MediaType.APPLICATION_JSON_PATCH_JSON)
@ -261,6 +268,7 @@ public class DatabaseResource {
@PUT
@Operation(summary = "Create or update database", tags = "databases",
description = "Create a database, it it does not exist or update an existing database.",
responses = {
@ApiResponse(responseCode = "200", description = "The updated database ",
content = @Content(mediaType = "application/json",
@ -280,6 +288,7 @@ public class DatabaseResource {
@DELETE
@Path("/{id}")
@Operation(summary = "Delete a database", tags = "databases",
description = "Delete a database by `id`. Database can only be deleted if it has no tables.",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Database for instance {id} is not found")

View File

@ -121,6 +121,9 @@ public class TableResource {
@GET
@Operation(summary = "List tables", tags = "tables",
description = "Get a list of tables, optionally filtered by `database` it belongs to. Use `fields` " +
"parameter to get only necessary fields. Use cursor-based pagination to limit the number " +
"entries in the list using `limit` and `before` or `after` query params.",
responses = {@ApiResponse(responseCode = "200", description = "List of tables",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = TableList.class)))
@ -139,7 +142,7 @@ public class TableResource {
@Min(1)
@Max(1000000)
@QueryParam("limit") int limitParam,
@Parameter(description = "Returns list of tables before this curor",
@Parameter(description = "Returns list of tables before this cursor",
schema = @Schema(type = "string"))
@QueryParam("before") String before,
@Parameter(description = "Returns list of tables after this curor",
@ -176,6 +179,7 @@ public class TableResource {
@GET
@Path("/{id}")
@Operation(summary = "Get a table", tags = "tables",
description = "Get a table by `id`",
responses = {
@ApiResponse(responseCode = "200", description = "table",
content = @Content(mediaType = "application/json",
@ -195,7 +199,8 @@ public class TableResource {
@GET
@Path("/name/{fqn}")
@Operation(summary = "Get a table by fully qualified name", tags = "tables",
@Operation(summary = "Get a table by name", tags = "tables",
description = "Get a table by fully qualified table name.",
responses = {
@ApiResponse(responseCode = "200", description = "table",
content = @Content(mediaType = "application/json",
@ -216,6 +221,7 @@ public class TableResource {
@POST
@Operation(summary = "Create a table", tags = "tables",
description = "Create a new table under an existing `database`.",
responses = {
@ApiResponse(responseCode = "200", description = "table",
content = @Content(mediaType = "application/json",
@ -236,6 +242,7 @@ public class TableResource {
@PUT
@Operation(summary = "Create or update a table", tags = "tables",
description = "Create a table, if it does not exist. If a table already exists, update the table.",
responses = {
@ApiResponse(responseCode = "200", description = "The table",
content = @Content(mediaType = "application/json",
@ -258,6 +265,7 @@ public class TableResource {
@PATCH
@Path("/{id}")
@Operation(summary = "Update a table", tags = "tables",
description = "Update an existing table using JsonPatch.",
externalDocs = @ExternalDocumentation(description = "JsonPatch RFC",
url = "https://tools.ietf.org/html/rfc6902"))
@Consumes(MediaType.APPLICATION_JSON_PATCH_JSON)
@ -282,6 +290,7 @@ public class TableResource {
@DELETE
@Path("/{id}")
@Operation(summary = "Delete a table", tags = "tables",
description = "Delete a table by `id`. Table is not immediately deleted and is only marked as deleted.",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Table for instance {id} is not found")
@ -298,6 +307,7 @@ public class TableResource {
@PUT
@Path("/{id}/followers")
@Operation(summary = "Add a follower", tags = "tables",
description = "Add a user identified by `userId` as followed of this table",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Table for instance {id} is not found")
@ -317,7 +327,8 @@ public class TableResource {
@PUT
@Path("/{id}/joins")
@Operation(summary = "Add table join information",
description = "Join information can only be added for last 30 days starting today", tags = "tables",
description = "Add information about other tables that this table is joined with. Join information can only" +
" be added for the last 30 days starting today.", tags = "tables",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Table for instance {id} is not found"),
@ -335,7 +346,8 @@ public class TableResource {
@PUT
@Path("/{id}/sampleData")
@Operation(summary = "Add sample data", tags = "tables")
@Operation(summary = "Add sample data", tags = "tables",
description = "Add sample data to the table." )
public Response addSampleData(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Parameter(description = "Id of the table", schema = @Schema(type = "string"))
@ -347,7 +359,8 @@ public class TableResource {
@DELETE
@Path("/{id}/followers/{userId}")
@Operation(summary = "Remove a follower", tags = "tables")
@Operation(summary = "Remove a follower", tags = "tables",
description = "Remove the user identified `userId` as a follower of the table.")
public Response deleteFollower(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Parameter(description = "Id of the table",

View File

@ -89,6 +89,7 @@ public class FeedResource {
@GET
@Operation(summary = "List threads", tags = "feeds",
description = "Get a list of threads, optionally filtered by `entityLink`.",
responses = {
@ApiResponse(responseCode = "200", description = "List of threads",
content = @Content(mediaType = "application/json",
@ -104,6 +105,7 @@ public class FeedResource {
@GET
@Path("/{id}")
@Operation(summary = "Get a thread", tags = "feeds",
description = "Get a thread by `id`.",
responses = {
@ApiResponse(responseCode = "200", description = "The thread",
content = @Content(mediaType = "application/json",
@ -116,6 +118,7 @@ public class FeedResource {
@POST
@Operation(summary = "Create a thread", tags = "feeds",
description = "Create a new thread. A thread is created about a data asset when a user posts the first post.",
responses = {
@ApiResponse(responseCode = "200", description = "The thread",
content = @Content(mediaType = "application/json",
@ -135,6 +138,7 @@ public class FeedResource {
@POST
@Path("/{id}/posts")
@Operation(summary = "Add post to a thread", tags = "feeds",
description = "Add a post to an existing thread.",
responses = {
@ApiResponse(responseCode = "200", description = "The post",
content = @Content(mediaType = "application/json",
@ -146,5 +150,4 @@ public class FeedResource {
Thread thread = addHref(uriInfo, dao.addPostToThread(id, post));
return Response.created(thread.getHref()).entity(thread).build();
}
}
}

View File

@ -93,6 +93,7 @@ public class MetricsResource {
@GET
@Operation(summary = "List metrics", tags = "metrics",
description = "Get a list of metrics. Use `fields` parameter to get only necessary fields.",
responses = {
@ApiResponse(responseCode = "200", description = "List of metrics",
content = @Content(mediaType = "application/json",
@ -101,17 +102,15 @@ public class MetricsResource {
public MetricsList list(@Context UriInfo uriInfo,
@Parameter(description = "Fields requested in the returned resource",
schema = @Schema(type = "string", example = FIELDS))
@QueryParam("fields") String fieldsParam,
@Parameter(description = "Get metrics that match fullyQualifiedName",
schema = @Schema(type = "string", example = "snowflakeWestCoast.finances"))
@QueryParam("fqn") String fqn) throws IOException {
@QueryParam("fields") String fieldsParam) throws IOException {
Fields fields = new Fields(FIELD_LIST, fieldsParam);
return new MetricsList(addHref(uriInfo, dao.list(fields, fqn)));
return new MetricsList(addHref(uriInfo, dao.list(fields)));
}
@GET
@Path("/{id}")
@Operation(summary = "Get a metric", tags = "metrics",
description = "Get a metric by `id`.",
responses = {
@ApiResponse(responseCode = "200", description = "The metrics",
content = @Content(mediaType = "application/json",
@ -129,6 +128,7 @@ public class MetricsResource {
@POST
@Operation(summary = "Create a metric", tags = "metrics",
description = "Create a new metric.",
responses = {
@ApiResponse(responseCode = "200", description = "The metric",
content = @Content(mediaType = "application/json",
@ -143,6 +143,7 @@ public class MetricsResource {
@PUT
@Operation(summary = "Create or update a metric", tags = "metrics",
description = "Create a new metric, if it does not exist or update an existing metric.",
responses = {
@ApiResponse(responseCode = "200", description = "The metric",
content = @Content(mediaType = "application/json",

View File

@ -84,6 +84,7 @@ public class PipelineResource {
@GET
@Operation(summary = "List pipelines", tags = "pipelines",
description = "Get a list of pipelines.",
responses = {
@ApiResponse(responseCode = "200", description = "List of pipelines",
content = @Content(mediaType = "application/json",
@ -96,6 +97,7 @@ public class PipelineResource {
@GET
@Path("/{id}")
@Operation(summary = "Get a pipeline", tags = "pipelines",
description = "Get a pipeline by `id`.",
responses = {
@ApiResponse(responseCode = "200", description = "The pipeline",
content = @Content(mediaType = "application/json",
@ -108,6 +110,7 @@ public class PipelineResource {
@POST
@Operation(summary = "Create a pipeline", tags = "pipelines",
description = "Create a new pipeline.",
responses = {
@ApiResponse(responseCode = "200", description = "The pipeline",
content = @Content(mediaType = "application/json",

View File

@ -93,6 +93,7 @@ public class ReportResource {
@GET
@Operation(summary = "List reports", tags = "reports",
description = "Get a list of reports. Use `fields` parameter to get only necessary fields.",
responses = {
@ApiResponse(responseCode = "200", description = "List of reports",
content = @Content(mediaType = "application/json",
@ -101,17 +102,15 @@ public class ReportResource {
public ReportList list(@Context UriInfo uriInfo,
@Parameter(description = "Fields requested in the returned resource",
schema = @Schema(type = "string", example = FIELDS))
@QueryParam("fields") String fieldsParam,
@Parameter(description = "Get report that match fullyQualifiedName",
schema = @Schema(type = "string", example = "snowflakeWestCoast.finances"))
@QueryParam("fqn") String fqn) throws IOException {
@QueryParam("fields") String fieldsParam) throws IOException {
Fields fields = new Fields(FIELD_LIST, fieldsParam);
return new ReportList(addHref(uriInfo, dao.list(fields, fqn)));
return new ReportList(addHref(uriInfo, dao.list(fields)));
}
@GET
@Path("/{id}")
@Operation(summary = "Get a report", tags = "reports",
description = "Get a report by `id`.",
responses = {
@ApiResponse(responseCode = "200", description = "The report",
content = @Content(mediaType = "application/json",
@ -128,6 +127,7 @@ public class ReportResource {
@POST
@Operation(summary = "Create a report", tags = "reports",
description = "Create a new report.",
responses = {
@ApiResponse(responseCode = "200", description = "The report",
content = @Content(mediaType = "application/json",
@ -142,6 +142,7 @@ public class ReportResource {
@PUT
@Operation(summary = "Create or update a report", tags = "reports",
description = "Create a new report, it it does not exist or update an existing report.",
responses = {
@ApiResponse(responseCode = "200", description = "The report",
content = @Content(mediaType = "application/json",

View File

@ -73,7 +73,9 @@ public class SearchResource {
@GET
@Path("/query")
@Operation(summary = "Search Entities", tags = "search",
@Operation(summary = "Search entities", tags = "search",
description = "Search entities using query test. Use query params `from` and `size` for pagination. Use " +
"`sort_field` to sort the results in `sort_order`.",
responses = {
@ApiResponse(responseCode = "200", description = "search response",
content = @Content(mediaType = "application/json",
@ -86,7 +88,7 @@ public class SearchResource {
"1. For listing all tables pass q=* <br/>" +
"2. For search tables pass q=*search_term* <br/>" +
"3. For searching field names such as search by column_name " +
"pass q=column_naemes:address <br/>" +
"pass q=column_names:address <br/>" +
"4. For searching by tag names pass q=tags:user.email <br/>" +
"5. When user selects a filter pass q=query_text AND tags:user.email " +
"AND platform:MYSQL <br/>" +
@ -148,7 +150,8 @@ public class SearchResource {
@GET
@Path("/suggest")
@Operation(summary = "Suggest Entities", tags = "search",
@Operation(summary = "Suggest entities", tags = "search",
description = "Get suggested entities used for auto-completion.",
responses = {
@ApiResponse(responseCode = "200",
description = "Table Suggestion API",

View File

@ -53,6 +53,7 @@ public class ServiceResource {
@GET
@Operation(summary = "List service collections", tags = "services",
description = "Get a list of resources under service collection.",
responses = {
@ApiResponse(responseCode = "200", description = "List of serviceCollections",
content = @Content(mediaType = "application/json",

View File

@ -94,6 +94,7 @@ public class DatabaseServiceResource {
@GET
@Operation(summary = "List database services", tags = "services",
description = "Get a list of database services.",
responses = {
@ApiResponse(responseCode = "200", description = "List of database service instances",
content = @Content(mediaType = "application/json",
@ -105,7 +106,8 @@ public class DatabaseServiceResource {
@GET
@Path("/{id}")
@Operation(summary = "Get database service", tags = "services",
@Operation(summary = "Get a database service", tags = "services",
description = "Get a database service by `id`.",
responses = {
@ApiResponse(responseCode = "200", description = "Database service instance",
content = @Content(mediaType = "application/json",
@ -121,6 +123,7 @@ public class DatabaseServiceResource {
@GET
@Path("/name/{name}")
@Operation(summary = "Get database service by name", tags = "services",
description = "Get a database service by the service `name`.",
responses = {
@ApiResponse(responseCode = "200", description = "Database service instance",
content = @Content(mediaType = "application/json",
@ -135,6 +138,7 @@ public class DatabaseServiceResource {
@POST
@Operation(summary = "Create database service", tags = "services",
description = "Create a new database service.",
responses = {
@ApiResponse(responseCode = "200", description = "Database service instance",
content = @Content(mediaType = "application/json",
@ -156,7 +160,8 @@ public class DatabaseServiceResource {
@PUT
@Path("/{id}")
@Operation(summary = "Update database service", tags = "services",
@Operation(summary = "Update a database service", tags = "services",
description = "Update an existing database service identified by `id`.",
responses = {
@ApiResponse(responseCode = "200", description = "Database service instance",
content = @Content(mediaType = "application/json",
@ -176,7 +181,9 @@ public class DatabaseServiceResource {
@DELETE
@Path("/{id}")
@Operation(summary = "Delete database service", tags = "services",
@Operation(summary = "Delete a database service", tags = "services",
description = "Delete a database services. If databases (and tables) belong the service, it can't be " +
"deleted.",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "DatabaseService service for instance {id} " +

View File

@ -27,6 +27,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.apache.maven.shared.utils.io.IOUtil;
import org.openmetadata.catalog.jdbi3.TagRepository;
import org.openmetadata.catalog.resources.Collection;
import org.openmetadata.catalog.security.CatalogAuthorizer;
import org.openmetadata.catalog.security.SecurityUtil;
import org.openmetadata.catalog.type.CreateTag;
import org.openmetadata.catalog.type.CreateTagCategory;
@ -36,7 +37,6 @@ import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.JsonUtils;
import org.openmetadata.catalog.util.RestUtil;
import org.openmetadata.catalog.util.ResultList;
import org.openmetadata.catalog.security.CatalogAuthorizer;
import org.openmetadata.common.utils.CommonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -117,6 +117,7 @@ public class TagResource {
@GET
@Operation(summary = "List tag categories", tags = "tags",
description = "Get a list of tag categories.",
responses = {
@ApiResponse(responseCode = "200", description = "The user ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation =
@ -136,6 +137,8 @@ public class TagResource {
@GET
@Path("{category}")
@Operation(summary = "Get a tag category", tags = "tags",
description = "Get a tag category identified by name. The response includes tag category information along " +
"with the entire hierarchy of all the children tags.",
responses = {
@ApiResponse(responseCode = "200", description = "The user ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation =
@ -156,6 +159,8 @@ public class TagResource {
@GET
@Operation(summary = "Get a primary tag", tags = "tags",
description = "Get a primary tag identified by name. The response includes with the entire hierarchy of all" +
" the children tags.",
responses = {
@ApiResponse(responseCode = "200", description = "The user ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation =
@ -187,6 +192,7 @@ public class TagResource {
@GET
@Path("{category}/{primaryTag}/{secondaryTag}")
@Operation(summary = "Get a secondary tag", tags = "tags",
description = "Get a secondary tag identified by name.",
responses = {
@ApiResponse(responseCode = "200", description = "The user ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation =
@ -221,6 +227,8 @@ public class TagResource {
@POST
@Operation(summary = "Create a tag category", tags = "tags",
description = "Create a new tag category. The request can include the children tags to be created along " +
"with the tag category.",
responses = {
@ApiResponse(responseCode = "200", description = "The user ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation =
@ -240,6 +248,7 @@ public class TagResource {
@POST
@Path("{category}")
@Operation(summary = "Create a primary tag", tags = "tags",
description = "Create a primary tag in the given tag category.",
responses = {
@ApiResponse(responseCode = "200", description = "The user ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation =
@ -263,6 +272,7 @@ public class TagResource {
@POST
@Path("{category}/{primaryTag}")
@Operation(summary = "Create a secondary tag", tags = "tags",
description = "Create a secondary tag under the given primary tag.",
responses = {
@ApiResponse(responseCode = "200", description = "The user ",
content = @Content(mediaType = "application/json", schema = @Schema(implementation =
@ -291,7 +301,8 @@ public class TagResource {
@PUT
@Path("{category}")
@Operation(summary = "Update an existing tag category", tags = "tags")
@Operation(summary = "Update a tag category", tags = "tags",
description = "Update an existing category identify by category name")
public Response updateCategory(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Parameter(description = "Tag category name",
@ -308,7 +319,8 @@ public class TagResource {
@PUT
@Path("{category}/{primaryTag}")
@Operation(summary = "Update an existing primaryTag", tags = "tags")
@Operation(summary = "Update a primaryTag", tags = "tags",
description = "Update an existing primaryTag identify by name")
public Response updatePrimaryTag(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Parameter(description = "Tag category name",
@ -330,7 +342,8 @@ public class TagResource {
@PUT
@Path("{category}/{primaryTag}/{secondaryTag}")
@Operation(summary = "Update an existing primaryTag", tags = "tags")
@Operation(summary = "Update a secondaryTag", tags = "tags",
description = "Update an existing secondaryTag identify by name")
public Response updateSecondaryTag(@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Parameter(description = "Tag category name",

View File

@ -113,6 +113,9 @@ public class TeamResource {
@GET
@Valid
@Operation(summary = "List teams", tags = "teams",
description = "Get a list of teams. Use `fields` " +
"parameter to get only necessary fields. Use cursor-based pagination to limit the number " +
"entries in the list using `limit` and `before` or `after` query params.",
responses = {
@ApiResponse(responseCode = "200", description = "List of teams",
content = @Content(mediaType = "application/json",
@ -167,6 +170,7 @@ public class TeamResource {
@Valid
@Path("/{id}")
@Operation(summary = "Get a team", tags = "teams",
description = "Get a team by `id`.",
responses = {
@ApiResponse(responseCode = "200", description = "The team",
content = @Content(mediaType = "application/json",
@ -187,6 +191,7 @@ public class TeamResource {
@Valid
@Path("/name/{name}")
@Operation(summary = "Get a team by name", tags = "teams",
description = "Get a team by `name`.",
responses = {
@ApiResponse(responseCode = "200", description = "The team",
content = @Content(mediaType = "application/json",
@ -205,6 +210,7 @@ public class TeamResource {
@POST
@Operation(summary = "Create a team", tags = "teams",
description = "Create a new team.",
responses = {
@ApiResponse(responseCode = "200", description = "The team",
content = @Content(mediaType = "application/json",
@ -226,6 +232,7 @@ public class TeamResource {
@Path("/{id}")
@Consumes(MediaType.APPLICATION_JSON_PATCH_JSON)
@Operation(summary = "Update a team", tags = "teams",
description = "Update an existing team with JsonPatch.",
externalDocs = @ExternalDocumentation(description = "JsonPatch RFC",
url = "https://tools.ietf.org/html/rfc6902"))
public Team patch(@Context UriInfo uriInfo,
@ -246,6 +253,7 @@ public class TeamResource {
@DELETE
@Path("/{id}")
@Operation(summary = "Delete a team", tags = "teams",
description = "Delete a team by given `id`.",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Team for instance {id} is not found")

View File

@ -116,6 +116,9 @@ public class UserResource {
@GET
@Valid
@Operation(summary = "List users", tags = "users",
description = "Get a list of users. Use `fields` " +
"parameter to get only necessary fields. Use cursor-based pagination to limit the number " +
"entries in the list using `limit` and `before` or `after` query params.",
responses = {
@ApiResponse(responseCode = "200", description = "The user ",
content = @Content(mediaType = "application/json",
@ -170,6 +173,7 @@ public class UserResource {
@Valid
@Path("/{id}")
@Operation(summary = "Get a user", tags = "users",
description = "Get a user by `id`",
responses = {
@ApiResponse(responseCode = "200", description = "The user",
content = @Content(mediaType = "application/json",
@ -189,6 +193,7 @@ public class UserResource {
@Valid
@Path("/name/{name}")
@Operation(summary = "Get a user by name", tags = "users",
description = "Get a user by `name`.",
responses = {
@ApiResponse(responseCode = "200", description = "The user",
content = @Content(mediaType = "application/json",
@ -209,6 +214,7 @@ public class UserResource {
@Valid
@Path("/loggedInUser")
@Operation(summary = "Get current logged in user", tags = "users",
description = "Get the user who is authenticated and is currently logged in.",
responses = {
@ApiResponse(responseCode = "200", description = "The user",
content = @Content(mediaType = "application/json",
@ -227,6 +233,7 @@ public class UserResource {
@POST
@Operation(summary = "Create a user", tags = "users",
description = "Create a new user.",
responses = {
@ApiResponse(responseCode = "200", description = "The user ",
content = @Content(mediaType = "application/json",
@ -250,6 +257,7 @@ public class UserResource {
@Path("/{id}")
@Consumes(MediaType.APPLICATION_JSON_PATCH_JSON)
@Operation(summary = "Update a user", tags = "users",
description = "Update an existing user using JsonPatch.",
externalDocs = @ExternalDocumentation(description = "JsonPatch RFC",
url = "https://tools.ietf.org/html/rfc6902"))
public User patch(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @PathParam("id") String id,
@ -269,8 +277,8 @@ public class UserResource {
@DELETE
@Path("/{id}")
@Operation(summary = "Deactivate a user", tags = "users",
description = "Users can't be deleted but are deactiveated. The name and display name is changed to include" +
" string `deactivated`.",
description = "Users can't be deleted but are deactivated. The name and display name is prefixed with " +
"the string `deactivated`.",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "User for instance {id} is not found")

View File

@ -70,7 +70,8 @@ public class UsageResource {
@GET
@Valid
@Path("/{entity}/{id}")
@Operation(summary = "Get usage of an entity", tags = "usage",
@Operation(summary = "Get usage", tags = "usage",
description = "Get usage details for an entity identified by `id`.",
responses = {
@ApiResponse(responseCode = "200", description = "Entity usage",
content = @Content(mediaType = "application/json",
@ -103,7 +104,8 @@ public class UsageResource {
@GET
@Valid
@Path("/{entity}/name/{fqn}")
@Operation(summary = "Get usage of an entity by name", tags = "usage",
@Operation(summary = "Get usage by name", tags = "usage",
description = "Get usage details for an entity identified by fully qualified name.",
responses = {
@ApiResponse(responseCode = "200", description = "Entity usage",
content = @Content(mediaType = "application/json",
@ -136,7 +138,9 @@ public class UsageResource {
@POST
@Path("/{entity}/{id}")
@Operation(summary = "Report usage information for an entity", tags = "usage",
@Operation(summary = "Report usage", tags = "usage",
description = "Report usage information for an entity on a given date. System stores last 30 days of usage " +
"information. Usage information older than 30 days is deleted.",
responses = {
@ApiResponse(responseCode = "200", description = "Usage information",
content = @Content(mediaType = "application/json",
@ -162,7 +166,9 @@ public class UsageResource {
@POST
@Path("/{entity}/name/{fqn}")
@Operation(summary = "Post usage information for an entity by name", tags = "usage",
@Operation(summary = "Report usage by name", tags = "usage",
description = "Report usage information for an entity by name on a given date. System stores last 30 days " +
"of usage information. Usage information older than 30 days is deleted.",
responses = {
@ApiResponse(responseCode = "200", description = "Usage information",
content = @Content(mediaType = "application/json",
@ -187,7 +193,8 @@ public class UsageResource {
@POST
@Path("/compute.percentile/{entity}/{date}")
@Operation(summary = "Compute percentiles for an entity on a given day", tags = "usage",
@Operation(summary = "Compute percentiles", tags = "usage",
description = "Compute percentile ranking for an entity based on last 30 days of usage.",
responses = {
@ApiResponse(responseCode = "201", description = "Percentiles computed"),
@ApiResponse(responseCode = "400", description = "Bad request")
@ -199,9 +206,8 @@ public class UsageResource {
@PathParam("entity") String entity,
@Parameter(description = "ISO 8601 format date to compute percentile on",
schema = @Schema(type = "string", example = "2021-01-28"))
@PathParam("date") String date,
@Parameter(description = "Usage information a given date")
@Valid DailyCount usage) {
@PathParam("date") String date) {
// TODO delete this?
dao.computePercentile(entity, date);
return Response.status(Response.Status.CREATED).build();
}

View File

@ -16,11 +16,11 @@
package org.openmetadata.catalog.resources.version;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import org.openmetadata.catalog.CatalogApplication;
import org.openmetadata.catalog.api.CatalogVersion;
import org.openmetadata.catalog.resources.Collection;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -59,7 +59,8 @@ public class VersionResource {
public VersionResource() {}
@GET
@Operation(summary = "Get version of metadata service", tags = "")
@Operation(summary = "Get version of metadata service", tags = "general",
description = "Get the build version of OpenMetadata service and build timestamp.")
public CatalogVersion getCatalogVersion() {
return CATALOG_VERSION;
}

View File

@ -223,6 +223,7 @@
"description": "Information on other tables that this table column is frequently joined with",
"properties": {
"columns": {
"description": "List of local column names (not fully qualified column names) of the table",
"type": "array",
"items": {
"$ref": "#/definitions/columnName"
@ -232,7 +233,7 @@
"description": "Data for a multiple rows of the table",
"type": "array",
"items": {
"description": "Data for a single row of the table",
"description": "Data for a single row of the table with in the same order as columns fields",
"type": "array"
}
}

View File

@ -1,7 +1,8 @@
# APIs
# Overview
OpenMetadata supports REST APIs for getting metadata in and out of metadata store. The API resources are grouped under following categories:
- **Data assets** - includes resources for data entities, such as `databases`, `tables`, and `topics`. Resources for data assets created from data, such as `dashboards`, `reports`, `metrics`, and `ML Features` are part of this collection. `pipelines`, `notebooks`, etc. that are used for creating data assets are also available as resources as of this collection.
- **Teams and Users** - includes `users`, `teams`, a special type of user called `bots` that performs many automated tasks such as ingestion.
- **Services** - are services that OpenMetadata integrates with. Currently `databaseService` is the only service under this collection that represents data sources. In the future, services related to Dashboards, Reports, ETL pipelines will be added under this collection.
- **Glossary** - OpenMetadata supports hierarchical tags that can be used to build business vocabulary to describe and classify data available under `tags` resource.
OpenMetadata supports REST APIs for getting data in and out of metadata system. APIs are built using current best practices of REST API design.
TODO add links to the various parts of the document
[Click here](http://localhost:8585/api/swagger) for Swagger API Documentation