Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions docs/AddUpdateWithAPIArtifact.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
Add/Update API with API Artifact
==============================

This guide describes how to create or update APIs using a single `apiArtifact` upload.

Supported endpoints
-------------------

- Create API (org): `POST /devportal/organizations/{organizationID}/apis`
- Create API (S2S): `POST /devportal/apis`
- Update API (org): `PUT /devportal/organizations/{organizationID}/apis/{apiID}`
- Update API (S2S): `PUT /devportal/apis/{apiID}`

Multipart field
---------------

Use the multipart field below:

- `apiArtifact`: zip file containing metadata, definition, and optional content.

Recommended artifact structure
------------------------------

```text
manifest.yaml # optional
devportal-api.yaml # required (metadata)
devportal-api-definition.yaml # required (API definition)
docs/ # optional (markdown docs)
apiContent/ # optional (landing files + images)
```

Optional `manifest.yaml`
------------------------

Use this only if your artifact uses non-default paths.

```yaml
apiMetadataPath: devportal-api.yaml
apiDefinitionPath: devportal-api-definition.yaml
docsPath: docs
apiContentPath: apiContent
```

Sample `devportal-api.yaml`
---------------------------

```yaml
apiVersion: devportal.api-platform.wso2.com/v1
kind: RestApi # RestApi | WS | GraphQL | SOAP | WebSubApi

metadata:
name: pizzashack-api-v1.0 # internal API handle

spec:
displayName: PizzaShackAPI
version: 1.0.0
description: This is a simple API for Pizza Shack
provider: WSO2
# referenceID: <uuid-from-control-plane>

tags:
- pizza

labels:
- default

subscriptionPolicies:
- Gold
- Bronze

visibility: PRIVATE
visibleGroups:
- HR

businessInformation:
businessOwner: Jane Roe
businessOwnerEmail: marketing@pizzashack.com
technicalOwner: John Doe
technicalOwnerEmail: architecture@pizzashack.com

endpoints:
sandboxUrl: https://sand.example.com/pizzashack/v1/api/
productionUrl: https://prod.example.com/pizzashack/v1/api/
```

Create with artifact (example)
------------------------------

```bash
curl --location --request POST 'http://localhost:3000/devportal/organizations/{organizationID}/apis' \
--header 'Authorization: Bearer <access_token>' \
--form 'apiArtifact=@"{path-to-api-artifact.zip}"'
```

Update with artifact (example)
------------------------------

```bash
curl --location --request PUT 'http://localhost:3000/devportal/organizations/{organizationID}/apis/{apiID}' \
--header 'Authorization: Bearer <access_token>' \
--form 'apiArtifact=@"{path-to-api-artifact.zip}"'
```

Update behavior summary
-----------------------

- Metadata is updated from `devportal-api.yaml`.
- API definition is updated from `devportal-api-definition.yaml`.
- Subscription policy mappings are replaced by the artifact values.
- For docs, API landing content, and images:
- if a file/item in the artifact already exists, it is updated
- if it does not exist, it is created
- if it is not included in the artifact, the existing item is kept as-is (not deleted)
4 changes: 4 additions & 0 deletions src/routes/devportalRoute.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ router.post(
multipartHandler.fields([
{name: 'apiDefinition', maxCount: 1},
{name: 'schemaDefinition', maxCount: 1},
{name: 'apiArtifact', maxCount: 1},
]),
apiMetadataService.createAPIMetadata);
router.get('/organizations/:orgId/apis/:apiId', enforceSecuirty(constants.SCOPES.DEVELOPER), apiMetadataService.getAPIMetadata);
Expand All @@ -68,6 +69,7 @@ router.put(
multipartHandler.fields([
{name: 'apiDefinition', maxCount: 1},
{name: 'schemaDefinition', maxCount: 1},
{name: 'apiArtifact', maxCount: 1},
]),
apiMetadataService.updateAPIMetadata);
router.delete('/organizations/:orgId/apis/:apiId', enforceSecuirty(constants.SCOPES.DEVELOPER), apiMetadataService.deleteAPIMetadata);
Expand All @@ -90,6 +92,7 @@ router.post(
multipartHandler.fields([
{name: 'apiDefinition', maxCount: 1},
{name: 'schemaDefinition', maxCount: 1},
{name: 'apiArtifact', maxCount: 1},
]),
apiMetadataService.createAPIMetadata); // s2s applied
router.get('/apis', enforceSecuirty(constants.SCOPES.DEVELOPER), apiMetadataService.getAllAPIMetadata); // s2s applied
Expand All @@ -99,6 +102,7 @@ router.put(
multipartHandler.fields([
{name: 'apiDefinition', maxCount: 1},
{name: 'schemaDefinition', maxCount: 1},
{name: 'apiArtifact', maxCount: 1},
]),
apiMetadataService.updateAPIMetadata); // s2s applied
router.delete('/apis/:apiId', enforceSecuirty(constants.SCOPES.DEVELOPER), apiMetadataService.deleteAPIMetadata); // s2s applied
Expand Down
Loading