Getting Started with API Integrator

Requirements:

Contents

Introduction

The API Integrator contains a single component, APIClient. This is a generic component that provides a developer with all the tools they need to integrate with a RESTful API. Using this in conjuntion with /n software's Code Generation Service allows a developer to quickly and easily generate classes for any API. All examples used in this article can be downloaded from the service's page and clicking "Choose a demo definition".

The APIClient component has the ability to make HTTP and HTTPS requests. It will also listen for any responses. It can generate and parse through both XML and JSON. Parameters can be built and sent as part of the URL, a form, a query, or any other typically used mechanism for an API.

Code Generation

The Code Generation Service extends the capabilities of APIClient by automatically building classes using the component. This saves developers time (and of course money) when completing important projects.

For example, a simple PetStore API might have a GetPetByStatus operation. This operation could be defined as part of a Swagger file like below.

"/pet/findByStatus": {
	"get": {
		"tags": [
			"pet"
		],
		"summary": "Finds Pets by status",
		"description": "Multiple status values can be provided with comma separated strings",
		"operationId": "findPetsByStatus",
		"produces": [
			"application/xml",
			"application/json"
		],
		"parameters": [
			{
				"name": "status",
				"in": "query",
				"description": "Status values that need to be considered for filter",
				"required": true,
				"type": "array",
				"items": {
					"type": "string",
					"enum": [
						"available",
						"pending",
						"sold"
					],
					"default": "available"
				},
				"collectionFormat": "multi"
			}
		],
		"responses": {
			"200": {
				"description": "successful operation",
				"schema": {
					"type": "array",
					"items": {
						"$ref": "#/definitions/Pet"
					}
				}
			},
			"400": {
				"description": "Invalid status value"
			}
		},
		"security": [
			{
				"api_key": []
			}
		]
	}
}

After processing the document with the service, a method in the resultant classes would be generated like below.

public List<Pet> FindPetsByStatus(List<String> status) {
	Apiclient apiclient = InitApiClient("get", "/pet/findByStatus");
	List<String[]> validAuths = new List<String[]>();
	validAuths.Add(new String[] {"api_key", null});
	InitAuthentication(apiclient, validAuths);
	for (int i = 0; status != null && i < status.Count; i++) {
		apiclient.AddQueryParam("status", status[i]);
	}
	apiclient.SendRequest();
	if (apiclient.StatusCode == 200) {
		return Pet.ArrayDeserialize(apiclient.TransferredData, "/", OutputFormat, null);
	}
	if (apiclient.StatusCode == 400) {
		throw new InAPIException(String.Format("HTTP {0} error: Invalid status value Response: {1}.", 400, apiclient.TransferredData.Length > 0 ? apiclient.TransferredData : "null"));
	}
	throw new InAPIException(String.Format("Failed to get result. HTTP {0}: {1}.", apiclient.StatusCode, apiclient.StatusDescription));
}

As the example demonstrates, the generated code has everything necessary to not only make the request, but also handle the response appropriately. There is a definition for what to do with a HTTP 200 response, one for a 400 response, and a default response for any other status codes.

The code generation service will automatically throw an exception for any response received with a non-200 status code. For certain API's, a non-200 status code can still have a response with useful information in it. Simply change the code directly in the generated classes to not throw an exception to handle these cases.

Authentication

APIClient is capabable of authenticating with a service in a number of ways. This can be as simple as basic HTTP authentication or as complex as token access using the OAuth 2.0 specification. Any security scheme that can be used by the OpenAPI specification can also be used by APIClient. In addition, /n software has added support for one more type of authentication, aws4, which can be used to authenticate with Amazon's Web Services. This section will cover how security schemes are defined in a document and what the generated code looks like for a few different types of schemes.

Security schemes are defined through the security and securityDefinitions objects of an OpenAPI document.

Security Object

The security object defines which schemes will be used for a particular operation. It can also define which schemes are used for the entire API. Precisely what the security object applies to depends on the location of the object in the document. Placing the object at the top-level, directly in the swagger object, will instruct the code generator that the specified scheme(s) should be used for all operations in the API. Placing the member inside one of the path items will instruct the generator to override the scheme defined at the top-level and use the scheme defined at the operation-level.

The example below shows a single Path Item for the "addPet" operation. Near the bottom there is a security object with a single value, "api_key" inside. This instructs the Code Generator to use the security definition entitled "api_key" to complete the addPet operation. If there are several security schemes listed in the security object, they will be attempted in the order they appear. If one authentication scheme fails, then the next scheme will be attempted.

There is an array following the value which could be used to define the security scheme inside the security object. In general it is easier to define the scheme in the securityDefinitions object so it can be used by multiple operations.

"/pet": {
	"post": {
		"tags": [
			"pet"
		],
		"summary": "Add a new pet to the store",
		"description": "",
		"operationId": "addPet",
		"consumes": [
			"application/json",
			"application/xml"
		],
		"produces": [
			"application/xml",
			"application/json"
		],
		"parameters": [
			{
				"in": "body",
				"name": "body",
				"description": "Pet object that needs to be added to the store",
				"required": true,
				"schema": {
					"$ref": "#/definitions/Pet"
				}
			}
		],
		"responses": {
			"405": {
				"description": "Invalid input"
			}
		},
		"security": [
			{
				"api_key": []
			}
		]
	}
}

SecurityDefinitions Object

The securityDefinitions object provides more information on exactly how a security scheme should be used. For more information please refer to the OpenAPI specification.

"securityDefinitions": {
	"petstore_auth": {
		"type": "oauth2",
		"authorizationUrl": "http://petstore.swagger.io/oauth/dialog",
		"flow": "implicit",
		"scopes": {
			"write:pets": "modify pets in your account",
			"read:pets": "read your pets"
		}
	},
	"api_key": {
		"type": "apiKey",
		"name": "api_key",
		"in": "header"
	}
}

In the above example, the securityDefinitions object contains two definitions for two security schemes. They are titled "petstore_auth" and "api_key". The Code Generation Service does not impose any restrictions on what the schemes can be titled as long as the match the title in the security object.

The code generation handles all authentication with the InitAuthentication method inside the BaseApi class. Inside this method, each type of authentication is handled differently. Below are a number of examples for different security schemes.

Api Key

When using an Api Key for authentication, use a security defintion of type "apiKey", like in the below example document.

"api_key": {
	"type": "apiKey",
	"name": "api_key",
	"in": "header"
}

The members in the above definition instruct the Code Generation Service that any operation using a scheme named "api_key", should refer to this definition. Additionally, the api key itself should be placed in the headers of the request. Below is the code that would be generated and placed inside the InitAuthentication method.

if (authName.Equals("api_key")) {
	if (String.IsNullOrEmpty(_apiKey)) throw new InAPIException("API key is not specified.");
	apiclient.AddHeader("api_key", _apiKey);
	return;
}

Below is the actual header string that would be sent in a request. Note the "api_key" header. "special-key" is the actual api key in this case.

GET /v2/pet/findByStatus?status=pending HTTP/1.1
Host: petstore.swagger.io
Accept-Encoding: gzip, deflate
User-Agent: IPWorks HTTP Component - www.nsoftware.com
Connection: close
api_key: special-key

OAuth 2.0

When using OAuth for authentication, use a security defintion of type "oauth2". Many API's use some form of the OAuth 2.0 specification for authentication. The Code Generation Service can handle generating code for any type of OAuth flow. Looking closer at the "petstore_auth" in the securityDefinitions object, there are a number of properties defined.

"petstore_auth": {
	"type": "oauth2",
	"authorizationUrl": "http://petstore.swagger.io/oauth/dialog",
	"flow": "implicit",
	"scopes": {
		"write:pets": "modify pets in your account",
		"read:pets": "read your pets"
	}
}

The authorizationUrl tells the component where to redirect the user for authorization. Because the flow is "implicit", the token will be returned from the same server a user authorizes with. If the flow was instead "accessCode", then an authorizationUrl and tokenUrl would be required. scopes is not required, but the scopes will be requested if defined.

if (authName.Equals("petstore_auth")) {
	if (String.IsNullOrEmpty(_OAuthClientId)) throw new InAPIException("OAuthClientId is not specified.");
	if (String.IsNullOrEmpty(_OAuthClientSecret)) throw new InAPIException("OAuthClientSecret is not specified.");
	apiclient.OAuthClientId = _OAuthClientId;
	apiclient.OAuthClientSecret = _OAuthClientSecret;
	apiclient.OAuthServerAuthURL = "http://petstore.swagger.io/oauth/dialog";
	apiclient.OAuthGrantType = ApiclientOAuthGrantTypes.ogtImplicit;
	if (String.IsNullOrEmpty(scopes)) {
		apiclient.OAuthAuthorizationScope = "write:pets read:pets";
	} else {
		apiclient.OAuthAuthorizationScope = scopes;
	}
	return;
}

APIClient has one additional property that is useful when using OAuth, OAuthCacheFile. This property is set to a location on disk that stores a number of values related to OAuth. The available properties stored in the cache file are:

  • OauthGrantType
  • OauthClientID
  • OauthClientSecret
  • OauthServerAuthURL
  • OauthServerTokenURL
  • OauthAuthorizationScope
  • OauthToken
  • OauthRefreshToken
  • OauthTokenTimestamp
  • OauthTokenExpiresIn

By using a cache file, OAuth parameters don't have to be renegotiated for every session. Refresh tokens and other parameters stored in the file can be used instead of requiring a user to re-authenticate. An example of how to use this property will be covered in the Complete Example.

AWS Requests with Signature 4.0

The API Integrator offers one additional type of authentication not defined in the OpenAPI specification, aws4. This is Amazon's method of authentication when making requests. The required members of a aws4 security definition are type, x-awz-version-name, and x-awz-version-value. The below example uses aws4 to authenticate to Amazon's S3 service. This example can be downloaded from the Code Generation Service page.

"securityDefinitions": {
	"s3AWSAuth": {
		"description": "AWS V4 Signature",
		"type": "aws4",
		"x-awz-version-name": "x-amz-s3-version",
		"x-awz-version-value": "2009-02-01"
	}
}

The definition above produces the following code in the InitAuthentication method.

if (authName.Equals("s3AWSAuth")) {
	if (String.IsNullOrEmpty(_AWS4AccessKey)) throw new InAPIException("AWS4AccessKey is not specified.");
	if (String.IsNullOrEmpty(_AWS4SecretKey)) throw new InAPIException("AWS4SecretKey is not specified.");
	apiclient.AWS4AccessKey = _AWS4AccessKey;
	apiclient.AWS4SecretKey = _AWS4SecretKey;
	apiclient.AddHeader("x-amz-s3-version", "2009-02-01");
	return;
}

Complete Example

Once an OpenAPI document has been processed by the Code Generation Service, the generated classes will be ready to use. In this section Box.com's GetFolderItems operation will be used to retrieve the folder items and tie together the OpenAPI document to the generated code.

In the OpenAPI document for Box.com, the GetFolderItems operation is defined with the below Path Item. This operation will return a list of all items in a folder, along with their metadata, from Box.com.

"/folders/{FOLDER_ID}/items": {
	"get": {
		"operationId": "getFolderItems",
		"summary": "Get Folder’s Items",
		"description": "Retrieves the files and/or folders contained within this folder without any other metadata about the folder. Any attribute in the full files or folders objects can be passed in with the fields parameter to get specific attributes, and only those specific attributes back; otherwise, the mini format is returned for each item by default. Multiple attributes can be passed in separated by commas e.g. fields=name,created_at. Paginated results can be retrieved using the limit and offset parameters.",
		"parameters": [
			{
				"name": "FOLDER_ID",
				"in": "path",
				"required": true,
				"type": "string"
			},
			{
				"name": "fields",
				"description": "Attribute(s) to include in the response",
				"in": "query",
				"required": false,
				"type": "string"
			},
			{
				"name": "limit",
				"description": "The maximum number of items to return in a page. The default is 100 and the max is 1000.",
				"format": "int64",
				"in": "query",
				"required": false,
				"type": "integer"
			},
			{
				"name": "offset",
				"description": "The offset at which to begin the response. An offset of value of 0 will start at the beginning of the folder-listing. Note: If there are hidden items in your previous response, your next offset should be = offset + limit, not the # of records you received back. The default is 0.",
				"in": "query",
				"required": false,
				"type": "string"
			}
		],
		"responses": {
			"200": {
				"description": "A collection of items contained in the folder is returned.",
				"schema": {
					"$ref": "#/definitions/ItemReferenceList"
				}
			},
			"default": {
				"description": "Get Folder items error",
				"schema": {
					"$ref": "#/definitions/Error"
				}
			}
		},
		"tags": [
			"Folders"
		],
		"externalDocs": {
			"url": "https://docs.box.com/reference#get-a-folders-items"
		}
	}
}

There are a number of parameters defined, but not all are required. As you can see in the usage example below, any non-required fields can be passed null safely and the generated classes will take the appropriate action.

Box.FoldersApi foldersApi = new Box.FoldersApi();
foldersApi.OAuthClientId = OAUTH_CLIENT_ID;
foldersApi.OAuthClientSecret = OAUTH_CLIENT_SECRET;
foldersApi.OAuthCacheFile = OAUTH_CACHE_FILE;
ItemReferenceList itemList = foldersApi.GetFolderItems("40065208690", null, null, null);

foreach(ItemReference item in itemList.Entries)
{
	Debug.WriteLine(item.Name + " - " + item.Type);
}

The first time the example is run, a browser will open requesting that the user authorize their Box.com account. Because a cache file was set before initiating OAuth, any returned parameters will be stored. The second time the example is run, as long as a refresh token was returned in the first example, the user will not have to re-authenticate. For more granular control over the OAuth parameters, the OAuth-related events can be used to capture any parameters and store them however the developer wishes. This is useful if parameters should not be stored on disk for security reasons.

The response from the GetFolderItems operation is stored in a ItemReferenceList, which has a property, Entries. Entries is an array of ItemReference's. In the Path Item for the operation, the 200 status response contains a reference to ItemReferenceList in the definitions object. The Code Generation Service will respect the types defined for response and requests. If you define something as an object, a class will be generated for it. If you define something as an array, the code will contain a List<T> for the defintion. This is true for all possible types in the OpenAPI 2.0 specification.

For the above example, all of the possible returned types are defined in the definitions object of the document. For more information on what types are available and examples of describing more complex types, please refer to the OpenAPI specification itself.

Language Specifics

C# (.NET)

When working with the .NET Edition of the integrator all generated classes are contained in a single file, under one namespace defined in tags. This file can be used at any level of a solution, as with any other namespace.


Java

When working with the Java edition the defining OpenAPI document does not need to change, but the resultant classes will follow Java conventions and rules instead. For instance, in .NET all public classes can be stored in one file, under a common namespace. With Java, each public class needs to be in it's own file, as a part of a common package that respects the folder structure. When Java is selected as the language, a zip archive of source files becomes available. For instance, using the PetStore example, the below files would be generated instead of a single .cs file.


Side-by-Side Comparison

Regardless of the language chosen, the classes generated are very much the same, aside, of course, from syntatic differences. Below is the PetApi class from both languages.

namespace Petstore {
  public class PetApi : BaseApi {
    public void AddPet(Pet body) {
      Apiclient apiclient = InitApiClient("post", "/pet");
      List<String[]> validAuths = new List<String[]>();
      validAuths.Add(new String[] {"api_key", null});
      InitAuthentication(apiclient, validAuths);
      if (body != null) { apiclient.PostData = Pet.Serialize(body, InputFormat); }
      apiclient.SendRequest();
      if (apiclient.StatusCode == 405) {
        throw new InAPIException(String.Format("HTTP {0} error: Invalid input Response: {1}.", 405, apiclient.TransferredData.Length > 0 ? apiclient.TransferredData : "null"));
      }
    }
    public void UpdatePet(Pet body) {
      Apiclient apiclient = InitApiClient("put", "/pet");
      List<String[]> validAuths = new List<String[]>();
      validAuths.Add(new String[] {"api_key", null});
      InitAuthentication(apiclient, validAuths);
      if (body != null) { apiclient.PostData = Pet.Serialize(body, InputFormat); }
      apiclient.SendRequest();
      if (apiclient.StatusCode == 400) {
        throw new InAPIException(String.Format("HTTP {0} error: Invalid ID supplied Response: {1}.", 400, apiclient.TransferredData.Length > 0 ? apiclient.TransferredData : "null"));
      }
      if (apiclient.StatusCode == 404) {
        throw new InAPIException(String.Format("HTTP {0} error: Pet not found Response: {1}.", 404, apiclient.TransferredData.Length > 0 ? apiclient.TransferredData : "null"));
      }
      if (apiclient.StatusCode == 405) {
        throw new InAPIException(String.Format("HTTP {0} error: Validation exception Response: {1}.", 405, apiclient.TransferredData.Length > 0 ? apiclient.TransferredData : "null"));
      }
    }
    public List<Pet> FindPetsByStatus(List<String> status) {
      Apiclient apiclient = InitApiClient("get", "/pet/findByStatus");
      List<String[]> validAuths = new List<String[]>();
      validAuths.Add(new String[] {"api_key", null});
      InitAuthentication(apiclient, validAuths);
      for(int i = 0; status != null && i < status.Count ;i++) {
        apiclient.AddQueryParam("status", status[i]);
      }
      apiclient.SendRequest();
      if (apiclient.StatusCode == 200) {
        return Pet.ArrayDeserialize(apiclient.TransferredData, "/", OutputFormat, null);
      }
      if (apiclient.StatusCode == 400) {
        throw new InAPIException(String.Format("HTTP {0} error: Invalid status value Response: {1}.", 400, apiclient.TransferredData.Length > 0 ? apiclient.TransferredData : "null"));
      }
      throw new InAPIException(String.Format("Failed to get result. HTTP {0}: {1}.", apiclient.StatusCode, apiclient.StatusDescription));
    }
    public List<Pet> FindPetsByTags(List<String> tags) {
      Apiclient apiclient = InitApiClient("get", "/pet/findByTags");
      List<String[]> validAuths = new List<String[]>();
      validAuths.Add(new String[] {"api_key", null});
      InitAuthentication(apiclient, validAuths);
      for(int i = 0; tags != null && i < tags.Count ;i++) {
        apiclient.AddQueryParam("tags", tags[i]);
      }
      apiclient.SendRequest();
      if (apiclient.StatusCode == 200) {
        return Pet.ArrayDeserialize(apiclient.TransferredData, "/", OutputFormat, null);
      }
      if (apiclient.StatusCode == 400) {
        throw new InAPIException(String.Format("HTTP {0} error: Invalid tag value Response: {1}.", 400, apiclient.TransferredData.Length > 0 ? apiclient.TransferredData : "null"));
      }
      throw new InAPIException(String.Format("Failed to get result. HTTP {0}: {1}.", apiclient.StatusCode, apiclient.StatusDescription));
    }
    public Pet GetPetById(long petId) {
      Apiclient apiclient = InitApiClient("get", "/pet/{petId}");
      List<String[]> validAuths = new List<String[]>();
      validAuths.Add(new String[] {"api_key", null});
      InitAuthentication(apiclient, validAuths);
      apiclient.AddURLParam("petId", petId.ToString());
      apiclient.SendRequest();
      if (apiclient.StatusCode == 200) {
        return Pet.Deserialize(apiclient.TransferredData, "/", OutputFormat, null);
      }
      if (apiclient.StatusCode == 400) {
        throw new InAPIException(String.Format("HTTP {0} error: Invalid ID supplied Response: {1}.", 400, apiclient.TransferredData.Length > 0 ? apiclient.TransferredData : "null"));
      }
      if (apiclient.StatusCode == 404) {
        throw new InAPIException(String.Format("HTTP {0} error: Pet not found Response: {1}.", 404, apiclient.TransferredData.Length > 0 ? apiclient.TransferredData : "null"));
      }
      throw new InAPIException(String.Format("Failed to get result. HTTP {0}: {1}.", apiclient.StatusCode, apiclient.StatusDescription));
    }
    public void UpdatePetWithForm(long petId, String name, String status) {
      Apiclient apiclient = InitApiClient("post", "/pet/{petId}");
      List<String[]> validAuths = new List<String[]>();
      validAuths.Add(new String[] {"api_key", null});
      InitAuthentication(apiclient, validAuths);
      apiclient.AddURLParam("petId", petId.ToString());
      if (name   != null) apiclient.AddFormVar("name", name);
      if (status != null) apiclient.AddFormVar("status", status);
      apiclient.SendRequest();
      if (apiclient.StatusCode == 405) {
        throw new InAPIException(String.Format("HTTP {0} error: Invalid input Response: {1}.", 405, apiclient.TransferredData.Length > 0 ? apiclient.TransferredData : "null"));
      }
    }
    public void DeletePet(String api_key, long petId) {
      Apiclient apiclient = InitApiClient("delete", "/pet/{petId}");
      List<String[]> validAuths = new List<String[]>();
      validAuths.Add(new String[] {"api_key", null});
      InitAuthentication(apiclient, validAuths);
      if (api_key != null) apiclient.AddHeader("api_key", api_key);
      apiclient.AddURLParam("petId", petId.ToString());
      apiclient.SendRequest();
      if (apiclient.StatusCode == 400) {
        throw new InAPIException(String.Format("HTTP {0} error: Invalid ID supplied Response: {1}.", 400, apiclient.TransferredData.Length > 0 ? apiclient.TransferredData : "null"));
      }
      if (apiclient.StatusCode == 404) {
        throw new InAPIException(String.Format("HTTP {0} error: Pet not found Response: {1}.", 404, apiclient.TransferredData.Length > 0 ? apiclient.TransferredData : "null"));
      }
    }
    public ApiResponse UploadFile(long petId, String additionalMetadata, String file) {
      Apiclient apiclient = InitApiClient("post", "/pet/{petId}/uploadImage");
      List<String[]> validAuths = new List<String[]>();
      validAuths.Add(new String[] {"api_key", null});
      InitAuthentication(apiclient, validAuths);
      apiclient.AddURLParam("petId", petId.ToString());
      if (additionalMetadata != null) apiclient.AddFormVar("additionalMetadata", additionalMetadata);
      if (file               != null) apiclient.AddFileVar("file", file);
      apiclient.SendRequest();
      if (apiclient.StatusCode == 200) {
        return ApiResponse.Deserialize(apiclient.TransferredData, "/", OutputFormat, null);
      }
      throw new InAPIException(String.Format("Failed to get result. HTTP {0}: {1}.", apiclient.StatusCode, apiclient.StatusDescription));
    }
	}
}
package petstore;

import inapi.*;
import java.util.List;
import java.util.ArrayList;

public class PetApi extends BaseApi {
		public void addPet(Pet body) throws InAPIException {
			Apiclient apiclient = initApiClient("post", "/pet");
			List<String[]> validAuths = new ArrayList<String[]>();
			validAuths.add(new String[] {"api_key", null});
			initAuthentication(apiclient, validAuths);
			if (body != null) { apiclient.setPostData(Pet.serialize(body, getInputFormat())); }
			apiclient.sendRequest();
			if (apiclient.getStatusCode() == 405) {
				throw new InAPIException(String.format("HTTP %s error: Invalid input Response: %s.", 405, apiclient.getTransferredData().length > 0 ? new String(apiclient.getTransferredData()) : "null"));
			}
		}
		public void updatePet(Pet body) throws InAPIException {
			Apiclient apiclient = initApiClient("put", "/pet");
			List<String[]> validAuths = new ArrayList<String[]>();
			validAuths.add(new String[] {"api_key", null});
			initAuthentication(apiclient, validAuths);
			if (body != null) { apiclient.setPostData(Pet.serialize(body, getInputFormat())); }
			apiclient.sendRequest();
			if (apiclient.getStatusCode() == 400) {
				throw new InAPIException(String.format("HTTP %s error: Invalid ID supplied Response: %s.", 400, apiclient.getTransferredData().length > 0 ? new String(apiclient.getTransferredData()) : "null"));
			}
			if (apiclient.getStatusCode() == 404) {
				throw new InAPIException(String.format("HTTP %s error: Pet not found Response: %s.", 404, apiclient.getTransferredData().length > 0 ? new String(apiclient.getTransferredData()) : "null"));
			}
			if (apiclient.getStatusCode() == 405) {
				throw new InAPIException(String.format("HTTP %s error: Validation exception Response: %s.", 405, apiclient.getTransferredData().length > 0 ? new String(apiclient.getTransferredData()) : "null"));
			}
		}
		public List<Pet> findPetsByStatus(List<String> status) throws InAPIException {
			Apiclient apiclient = initApiClient("get", "/pet/findByStatus");
			List<String[]> validAuths = new ArrayList<String[]>();
			validAuths.add(new String[] {"api_key", null});
			initAuthentication(apiclient, validAuths);
			for(int i = 0; status != null && i < status.size() ;i++) {
				apiclient.addQueryParam("status", status.get(i));
			}
			apiclient.sendRequest();
			if (apiclient.getStatusCode() == 200) {
				return Pet.arrayDeserialize(new String(apiclient.getTransferredData()), "/", getOutputFormat(), null);
			}
			if (apiclient.getStatusCode() == 400) {
				throw new InAPIException(String.format("HTTP %s error: Invalid status value Response: %s.", 400, apiclient.getTransferredData().length > 0 ? new String(apiclient.getTransferredData()) : "null"));
			}
			throw new InAPIException(String.format("Failed to get result. HTTP %d: %s.", apiclient.getStatusCode(), apiclient.getStatusDescription()));
		}
		public List<Pet> findPetsByTags(List<String> tags) throws InAPIException {
			Apiclient apiclient = initApiClient("get", "/pet/findByTags");
			List<String[]> validAuths = new ArrayList<String[]>();
			validAuths.add(new String[] {"api_key", null});
			initAuthentication(apiclient, validAuths);
			for(int i = 0; tags != null && i < tags.size() ;i++) {
				apiclient.addQueryParam("tags", tags.get(i));
			}
			apiclient.sendRequest();
			if (apiclient.getStatusCode() == 200) {
				return Pet.arrayDeserialize(new String(apiclient.getTransferredData()), "/", getOutputFormat(), null);
			}
			if (apiclient.getStatusCode() == 400) {
				throw new InAPIException(String.format("HTTP %s error: Invalid tag value Response: %s.", 400, apiclient.getTransferredData().length > 0 ? new String(apiclient.getTransferredData()) : "null"));
			}
			throw new InAPIException(String.format("Failed to get result. HTTP %d: %s.", apiclient.getStatusCode(), apiclient.getStatusDescription()));
		}
		public Pet getPetById(Long petId) throws InAPIException {
			Apiclient apiclient = initApiClient("get", "/pet/{petId}");
			List<String[]> validAuths = new ArrayList<String[]>();
			validAuths.add(new String[] {"api_key", null});
			initAuthentication(apiclient, validAuths); 
			if (petId != null) apiclient.addURLParam("petId", petId.toString());
			apiclient.sendRequest();
			if (apiclient.getStatusCode() == 200) {
				return Pet.deserialize(new String(apiclient.getTransferredData()), "/", getOutputFormat(), null);
			}
			if (apiclient.getStatusCode() == 400) {
				throw new InAPIException(String.format("HTTP %s error: Invalid ID supplied Response: %s.", 400, apiclient.getTransferredData().length > 0 ? new String(apiclient.getTransferredData()) : "null"));
			}
			if (apiclient.getStatusCode() == 404) {
				throw new InAPIException(String.format("HTTP %s error: Pet not found Response: %s.", 404, apiclient.getTransferredData().length > 0 ? new String(apiclient.getTransferredData()) : "null"));
			}
			throw new InAPIException(String.format("Failed to get result. HTTP %d: %s.", apiclient.getStatusCode(), apiclient.getStatusDescription()));
		}
		public void updatePetWithForm(Long petId, String name, String status) throws InAPIException {
			Apiclient apiclient = initApiClient("post", "/pet/{petId}");
			List<String[]> validAuths = new ArrayList<String[]>();
			validAuths.add(new String[] {"api_key", null});
			initAuthentication(apiclient, validAuths); 
			if (petId  != null) apiclient.addURLParam("petId", petId.toString());
			if (name   != null) apiclient.addFormVar("name", name);
			if (status != null) apiclient.addFormVar("status", status);
			apiclient.sendRequest();
			if (apiclient.getStatusCode() == 405) {
				throw new InAPIException(String.format("HTTP %s error: Invalid input Response: %s.", 405, apiclient.getTransferredData().length > 0 ? new String(apiclient.getTransferredData()) : "null"));
			}
		}
		public void deletePet(String api_key, Long petId) throws InAPIException {
			Apiclient apiclient = initApiClient("delete", "/pet/{petId}");
			List<String[]> validAuths = new ArrayList<String[]>();
			validAuths.add(new String[] {"api_key", null});
			initAuthentication(apiclient, validAuths);
			if (api_key != null) apiclient.addHeader("api_key", api_key); 
			if (petId   != null) apiclient.addURLParam("petId", petId.toString());
			apiclient.sendRequest();
			if (apiclient.getStatusCode() == 400) {
				throw new InAPIException(String.format("HTTP %s error: Invalid ID supplied Response: %s.", 400, apiclient.getTransferredData().length > 0 ? new String(apiclient.getTransferredData()) : "null"));
			}
			if (apiclient.getStatusCode() == 404) {
				throw new InAPIException(String.format("HTTP %s error: Pet not found Response: %s.", 404, apiclient.getTransferredData().length > 0 ? new String(apiclient.getTransferredData()) : "null"));
			}
		}
		public ApiResponse uploadFile(Long petId, String additionalMetadata, String file) throws InAPIException {
			Apiclient apiclient = initApiClient("post", "/pet/{petId}/uploadImage");
			List<String[]> validAuths = new ArrayList<String[]>();
			validAuths.add(new String[] {"api_key", null});
			initAuthentication(apiclient, validAuths); 
			if (petId              != null) apiclient.addURLParam("petId", petId.toString());
			if (additionalMetadata != null) apiclient.addFormVar("additionalMetadata", additionalMetadata);
			if (file               != null) apiclient.addFileVar("file", file);
			apiclient.sendRequest();
			if (apiclient.getStatusCode() == 200) {
				return ApiResponse.deserialize(new String(apiclient.getTransferredData()), "/", getOutputFormat(), null);
			}
			throw new InAPIException(String.format("Failed to get result. HTTP %d: %s.", apiclient.getStatusCode(), apiclient.getStatusDescription()));
		}
	}

Getting Support

If you are stuck with API Integrator there are options for help. Please have a look through the Knowledge Base and Documentation first, as often many common questions can be answered there. If you are still having trouble, please open a support ticket and our support team would be happy to help you. Alternatively check out the other support options.


We appreciate your feedback.  If you have any questions, comments, or suggestions about this article please contact our support team at kb@nsoftware.com.