Приложно-програмен интерфейс
- Вижте пояснителната страница за други значения на Интерфейс.
Приложно-програмният интерфейс (на английски: application programming interface, API) е интерфейсът на изходния код, който операционната система или нейните библиотеки от ниско ниво предлагат за поддръжката на заявките от приложния софтуер или компютърните програми.
Образно казано, приложно-програмният интерфейс предоставя един по-абстрактен и опростен план за разработчика на приложения, който би му спестил изучаването на няколко различни слоя от Операционната или софтуерната система зад интерфейса. По този начин се достига ефективност и бързина при адаптирането на нови софтуерни технологии.
В миналото терминът се е използвал за обозначението на интерфейса между две програми.
Употреба
[редактиране | редактиране на кода]API в процедурните езици
[редактиране | редактиране на кода]В повечето процедурни езици приложно-програмния интерфейс (API) указва набор от функции или програми, които изпълняват определена задача или имат възможност за взаимодействие с определен софтуер. Тази спецификация е представена в разбираем за човека хартиен (при хартиените книги) или електронен формат (при електронните книги). Например математическото API в Unix системите указва начина, по който да се използват математическите функции, които са включени в математическата библиотека. Сред тези функции има функция, наречена sqrt()
, която се използва за изчисляването на корен квадратен от дадено число.
Unix командата man 3 sqrt
представя сигнатурата на функцията sqrt
в следния формат:
SYNOPSIS
#include <math.h>
double sqrt(double X);
float sqrtf(float X);
DESCRIPTION
sqrt изчислява корен квадратен от аргумента. ...
RETURNS
При успешно изчисляване като резултат се връща корен квадратен от аргумента...
Това описание означава, че функцията sqrt()
връща като резултат корен квадратен от положително дробно число друго дробно число.
Оттук следва, че в този случай API-то може да бъде разглеждано като колекция от вмъкнати файлове, използвани от дадена програма, написана на езика C, правеща препратка към тази библиотека и нейното описание на разбираем човешки език, предоставени от страниците за упътване.
По този начин други езици също имат процедурни библиотеки. Например езика Perl е посветил API за същата математическа задача с вградена документация, която е достъпна чрез помощната програма perldoc:
$ perldoc -f sqrt sqrt EXPR sqrt #Връща корен квадратен от EXPR. Ако EXPR е пропуснато, връща #корен квадратен от $_. Работи само върху неотрицателни операнди, освен ако #не сте заредили стандартния Math::Complex модул.
API в обектно-ориентираните езици
[редактиране | редактиране на кода]В своята най-проста форма обектното API представлява описание на начина, по който обектите работят в даден обектно-ориентиран език – най-често е представян като набор от класове със съответен списък на методите в класа.
Например в езика Java, ако трябва да се използва класа Scanner (клас, който чете данните, въведени от потребителя в текстова програма), е необходимо да се вмъкне и библиотеката java.util.Scanner
, като по този начин обектите от тип Scanner
може да се използват, като се извика някой от методите на класа:
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
System.out.println("Въведи твоето името:");
Scanner inputScanner = new Scanner(System.in);
String name = inputScanner.nextLine();
System.out.println("Твоето име е " + name + ".");
inputScanner.close();
}
}
В горния пример методите nextLine()
и close()
са част от API за класа Scanner
и следователно са описани в документацията на това API, например:
public String nextLine()
Advances this scanner past the current line and returns the skipped input...
Returns:
the line that was skipped
Throws:
NoSuchElementException
– if no line found
IllegalStateException
– if this scanner is closed
Като цяло, в обектно-ориентираните езици едно API обикновено включва описание на класове с група от поведения, свързани с тези класове. Тази абстрактна концепция е свързана с истинската функционалност на класовете, които се изпълняват по отношение на методите на класа (или по-общо казано от всички негови публични компоненти, като публичните методи, а също и всеки вътрешен компонент, който е направен публичен, като полета, константи, вмъкнати обекти, енумерации и др.).
API в този случай може да се разглежда като съвкупност от всички методи, които са направени публични от класовете (наричани често интерфейси). Това означава, че API определя методите, с които някой взаимодейства с обектите, които произлизат от дефинициите на класовете.
По-общо казано API може да бъде разглеждано като съвкупност от всички видове обекти, които могат да произлизат от дефинициите на класовете и свързаните с тях възможни поведения. Употребата на API се постига с помощта на публични методи, но в тази интерпретация, методите се разглеждат като технически детайл на начина по който е имплементирано поведението им.
Например, клас, представляващ Stack
може просто да представи публично два метода – push()
(добавя нов елемент към стека) и pop()
(премахва последния елемент, който се намира най-отгоре в стека).
В този случай това API може да се обясни като два метода pop()
и push()
, или по-общо казано като идея, при която някой може да използва елемент от тип Stack
, който имплементира (наследява) поведението на стека: една купчина, на която да се добавят или премахват нейните елементи, намиращи се най-отгоре в нея. Втората интерпретация изглежда по-подходяща в духа на обектното ориентиране.
Тази концепция може да бъде приложена до там, докъдето интерфейса на класа в едно API като цяло няма методи, а има само поведения, свързани с него. Например, API-тата на езиците Java и Lisp съдържат интерфейс с името Serializable, който е водещ интерфейс, изискващ всеки клас да го имплементира с поведението на класа serialized
. Това не изисква имплементация на публичен метод, а изисква всеки клас, който имплементира този интерфейс да бъде на основата на представяне, което може да бъде записано по всяко време.
По същия начин поведението на обект в многонишкова среда не е задължително да се определя от конкретни методи, принадлежащи на имплементирания интерфейс, но все още принадлежащи и на API-то за обектите от този клас, и би трябвало да бъде описано в документацията.
В този смисъл, в обектно-ориентираните езици, едно API дефинира колекция от поведението на обекти, вероятно предизвикани от методите на класа.
В подобни езици, едно API се разпространява като библиотека. Например, библиотеките на езика Java включват набор от API-та, които се предоставят под формата на JDK, използвани от разработчиците да създават нови Java приложения. Едно JDK включва документацията на API-то в JavaDoc формат.
Количеството на документацията, свързана с едно API често е фактор, определящ неговия успех по отношение на лекотата на използване.
API библиотеки и софтуерни рамки
[редактиране | редактиране на кода]Едно API често е свързвано със софтуерна библиотека: API-то описва и определя очакваното поведение, докато библиотеката е актуалната имплементация на този набор от правила. Едно API може да има множествена имплементация (или никаква – ако е абстрактно) под формата на различни библиотеки, които споделят един и същ програмен интерфейс.
Едно API може също да бъде свързано със софтуерна рамка: рамката може да бъде базирана на няколко библиотеки, имплементиращи няколко API-та, но за разлика от нормалното ползване на API-та, достъпа до поведението, което е вградено в рамката се осъществява чрез разширение на съдържанието му с нови класове, вмъкнати в самата библиотека. Освен цялостната програма за контрол на потока, може да бъде извън контрола на извикващия, и в ръцете на рамката чрез inversion of control или друг подобен механизъм.
API и протоколи
[редактиране | редактиране на кода]Едно API също така може да бъде и имплементация на протокол.
Когато едно API имплементира даден протокол, то може да бъде базирано на прокси методи за отдалечени извиквания, които отдолу разчитат на комуникационния протокол. Ролята на едно API може скриването точно подробностите от транспортния протокол. Например RMI е API, което имплементира протокола JRMR или IIOP като RMI-IIOP.
Обикновено протоколите се споделят между различни технологии (система, която е базирана на дадени компютърни програмни езици в дадена операционна система) и обикновено позволяват различните технологии да обменят информация, имайки ролята на посредник между две различни среди. Следователно протокола може да бъде считан като отдалечено API, докато локалните API-та обикновено са специфични за дадена технология. Ето защо едно API, което е създадено за дадена технология, не може да бъде използвано в други езици, освен ако извикванията на функция не са вмъкнати в конкретни библиотеки за адаптация.
За да бъде възможно обменянето на информация между системите, които използват различни технологии, когато едно API имплементира протокол, то може да предвижда формат за съобщение на неутрален език, например SOAP използва XML като общ контейнер на съобщенията, които трябва да бъдат обменяни, като по същия начин и REST API може да използва двете XML и JSON.
API за обмяна на обекти и протоколи
[редактиране | редактиране на кода]Едно обектно API може да предвижда специфичен формат за обмяна на обекти, който програмата може да използва локално в приложението, докато протокола за обмяна на обекти може да дефинира начина за трансфер на един и същ тип информация в съобщение, което е изпратено към отдалечена система.
Когато се обменят съобщения чрез протокол между две различни платформи, използвайки обекти от двете страни, обекта в програмния език може да бъде трансформиран в обект в отдалечения и различен език, например програма, която е написана на Java се обръща към услуга чрез SOAP или IIOP, написан на C#, като двете програми използват API-та за отдалечено извикване (всеки локално към машината, където те работят), за да обменят дистанционно информация, която двете конвертират от/към обект в локалната памет.
Вместо това когато подобен обект се обменя чрез API локално към една машина, то обекта се обменя ефективно в паметта, например чрез памет, предназначена за единствен процес, или между няколко процеса, използвайки споделена памет, сървърно приложение или други технологии за споделяне като tuple space.
Отдалечено API на обекти и протоколи
[редактиране | редактиране на кода]Отдалеченото API за обекти е базирано на отдалечен протокол, като CORBA, който позволява извикване на отдалечен обектен метод. Извикване на метод, който е изпълнен локално върху прокси обект, извиква съответния метод върху отдалечение обект, използвайки отдалечен протокол, като изисква резултата да бъде използван локално като връщана стойност.
Когато отдалечението е на място, модификация на прокси обекта отговаря на модификация на отдалечение обект. Когато имаме само трансфер на обект, модификацията на локалното копие на обекта не е рефлектирано върху оригиналния обект, освен ако обекта не е изпратен към изпращаща система.
Споделяне на API-та и преизползване чрез виртуална машина
[редактиране | редактиране на кода]Някои езици, като тези, които се изпълняват върху виртуална машина (например .NET CLI компилиращите езици в CLR-а, и JVM-компилиращите езици в Java виртуалната машина) могат да споделят API. В този случай виртуалната машина позволява взаимодействието между езиците, правещ абстрактен програмния език, използвайки междинен байт код и неговите езикови привързвания. В тези езици компилатора подготвя навременна компилация или преждевременна компилация, трансформирайки сорс кода, вероятно написан на няколко езика, в неговото независимо езиково байт код представяне.
Например чрез байт код представяне, програма, която е написана на езиците Groovy или Scala имат обектен модел, който е superset на този, който е на езика Java, така, че всяко API, което е представено чрез Java обект е достъпно чрез Groovy и Scala с еквивалентно извикване на обект, преведено в байт код.
От друга страна обектите от най-високо ниво, които не присъстват в Java като закривания. Тези обекти не могат да бъдат естествено представени в езика Java (Java 8 въведе концепцията за анонимна функция. Така, че за да даде възможност за много операции, closure е капсулирана в стандартен Java обект. В този случай извикването на closure е става с посредничещ метод, с името call()
, който често се представя в closure обект, както е при Java.
Уеб API
[редактиране | редактиране на кода]Уеб API е приложно-програмен интерфейс, предназначен за уеб сървър или уеб браузър. Концепцията за API е като архитектура, която се върти около предоставянето на програмни интерфейси към група от услуги към различни приложения, обслужвайки различни видове потребители. Когато се използва в контекста на уеб програмиране, едно API е дефинирано като група от HTTP извикващи съобщения, заедно с дефиниция на структурата на отговарящите съобщения, което обикновено е при Extensible Markup Language (XML) или Java Script Object Notation (JSON) формат. Докато „уеб API“ исторически е синоним на уеб услуга, според последните тенденции (така наречената Web 2.0) значението на термина се измества от Simple Object Access Protocol (SOAP) базирани уеб услуги и архитектура, ориентирана към услугите (SOA) към по-директно REST стил уеб източници и архитектура, ориентирана към източниците (ROA). Част от тази тенденция е свързана с движението на семантичния уеб към Resource Description Framework (RDF), концепция за промотиране на уеб базирани онтологични инженерни техлогии. Уеб API-тата позволяват комбинацията на множество API-та в нови приложения, известни като mashups.
Използването на уеб за споделяне на съдържание
[редактиране | редактиране на кода]Практиката за публикуване на API-та позволи на уеб общността да създава отворена архитектура за споделяне на съдържание и данни между общности и приложения. По този начин съдържание, което е създадено на едно място може динамично да бъде публикувано и обновено на няколко места в уеб пространството:
- Снимките могат да бъдат споделяни от сайтове, като Flickr и Photobucket към социални мрежи като Facebook и MySpace.
- Съдържанието може да бъде вмъкнато, като например вмъкване на презентация от SlideShare в LinkedIn профил.
- Съдържанието може да бъде публикувано динамично. Споделянето на коментари в реално време, направени в Twitter с Facebook акаунт например е възможно благодарение на техните API-та.
- Видео съдържание може да бъде вмъквано в сайтове, обслужвани от друг хост.
- Информация за потребителя може да бъде споделяна от уеб общността към външни приложения, предоставяйки нова функционалност на уеб обществото, което споделя неговите данни за потребителя чрез отворено API. Един от най-добрите примери за това е Facebook Application platform и Open Social platform.
- Ако съдържанието е директно представяне на физическия свят (например температура за някое място на земята) тогава едно API може да бъде считано за Environmental Programming Interface (EPI).
API дизайн
[редактиране | редактиране на кода]Няколко принципа се използват за управление на процеса за изработване на API дизайн. Парнас е предложил концепцията за скриване на информация през 1972 г. Принципът на скриване на информация е следния – някой може да разделя софтуера на модули, всеки от които има специфичен интерфейс. Интерфейсите крият детайлите за имплементация, така, че потребителите на модулите нямат нужда от това да разбират сложността на вътрешността на модулите. Тези интерфейси са API-та, и като резултат API-тата би трябвало да показват само тези детайли за модела, които клиентите трябва да знаят, за да използват модулите ефективно. Софтуерната архитектура е посветена на създаването и поддържането на софтуерни структури от най-високо ниво, нещо което обикновено включва и модули. По този начин една системна архитектура е сложно свързана с API-тата, които обясняват тази архитектура. Все пак доста решения, които са свързани със създаването на API-та не са архитектурни – такива като конвенциите за именуване, както и множеството детайли за начина по който са структурирани интерфейсите.
Тези детайли за начина, по който са структурирани интерфейсите, също като софтуерната архитектура, имат значително влияние върху качеството на софтуера. Например Каталдо е открил, че появата на бъгове е свързана със зависимостта от логическите операции и данните в софтуера. Това предполага, че за да се редуцират нивата на бъговете, софтуерните разработчици трябва внимателно да зависимостите между отделните API-та.
Законът на Конуей казва, че структурата на системата неминуемо рефлектира върху структурата на организацията, която го е създала. Това предполага, че за да се разбере как е направен дизайна на API-тата в истинския свят, трябва да се разберат и структурите на софтуерните инженерни организации. По подобен начин, една гупа от API трябва да бъде структурирана според нейните нужди. В едно изследване направено измежду 775 софтуерни инженери на Microsoft, Бегел е установил, че в допълнение на координацията относно API дизайна, софтуерните инженери много по-често правят координация помежду си относно сроковете и проблемите. Това потвърждава факта, че софтуерните организации си съдействат доста добре и че организационната структура е важна.
Няколко автора публикували съвети за начина, по който се прави дизайна на API-тата – Джошуа Блох и Мичи Хенинг са двама от тях. Все пак, тъй като един от принципите на API дизайна е той да бъде съвместим с другите API-та, които са вече в системата и работят, детайлите на API дизайна са езиково и системно независими.
Политики при публикуване на API
[редактиране | редактиране на кода]Основните принципи при публикуване на API-та са:
- Запазване на информацията върху API-тата от общата публика. Например Сони направиха API-то на техния официален PlayStation 2 достъпно само за лицензирани PlayStation разработчици. По този начин Sony могат да контролират разработчиците, които пишат игри за PlayStation 2. Това дава възможност на компаниите за привилегирован контрол на качеството и може да им донесе потенциални приходи от лицензиране.
- Правенето на API-та свободни. Например Microsoft направи API-то Microsoft Windows публично, а Apple пусна неговите API-та Carbon и Cocoa, така, че софтуера може да бъде написан за техните платформи.
Микс от двете поведения може също да бъде използван.
Последици от публичните API-та
[редактиране | редактиране на кода]Едно API може да бъде разработено за ограничен кръг от потребители, или може да бъде пуснато публично.
Един възможен фактор, когато едно API става публично устойчивостта на интерфейса му. Правенето на промени по част от него, например добавянето на нови параметри към функция, може да прекъсне съвместимостта с клиенти, които зависят от това API.
Когато части от публично публикувани API-та стават обект на промени, а по този начин стават и нестабилни, такива части от даденото API би трябвало да бъдат изрично документирани като нестабилни. Например в библиотеката Google Guava частите, които се считат за нестабилни и които могат да претърпят промени в близко бъдеще, с отбелязани с Java коментара @Beta
.
Остаряване на API-тата
[редактиране | редактиране на кода]Понякога едно публично API може да декларира някои свои части като остарели. Това обикновено означава, че такава част от API-то може да се счита като кандидат за премахване или промяна.
Когато работят с публични API от трети страни, разработчиците трябва да отчитат политиката за остарялост, използвана от създателя на това API – ако разработчикът пусне публично някакво решение, базирано на API, което е остаряло, то той няма да има възможност да гарантира стабилността на предлаганата услуга.
Видове
[редактиране | редактиране на кода]- функционални (напр. DLL)
- по данни (напр. Unix)
- обектно-ориентирани (напр. ActiveX-DLL)
- протоколни (например FTP, SOAP)
Функционалните програмни интерфейси разпознават само функции като средство за комуникация. При това почти винаги бива използвана така наречената handle концепция. В компютърни системи с handle се обозначават идентификатори за дигитални обекти. При извикването на една функция бива върнат обратно handle. С помощта на този handle могат да бъдат извиквани други функции, докато не трябва отново да бъде затворен. BIOS-ът на един персонален компютър е най-старият програмен интерфейс от този тип.
При програмните интерфейси по данни комуникацията се осъществява чрез извикването на стандартните команди open, read, write и close за обработването на файл системи. Ако дадени данни трябва да бъдат пратени на обект, то те биват написани с помощта на командата write. Ако дадени данни трябва да бъдат приети, то те биват прочетени с помощта на командата read. Този принцип е под UNIX широко разпространен при управляването на регулиращи механизми за уреди.
Обектно-ориентираните програмни интерфейси използват указатели към интерфейси.
Протоколните програмни интерфейси са независими от операционната система и хардуера на компютъра. За сметка на това протоколът трябва винаги да бъде програмиран наново. За да се ограничат до минимум средствата използвани за това, протоколният програмен интерфейс може да бъде свързан например с функционален интерфейс. Два вида протокола биват различавани – такива, които са зависими от приложението (например SMTP) и общи (например SOAP).
Примери за приложно-програмни интерфейси
[редактиране | редактиране на кода]- PC BIOS call interface
- Single UNIX Specification (SUS)
- Windows API
- Java Platform, Standard Edition API
- Java Platform, Enterprise Edition APIs
- ASPI за SCSI device interfacing
- Carbon и Cocoa за Macintosh OS
- OpenGL cross-platform 3D graphics API
- DirectX за Microsoft Windows
- Simple DirectMedia Layer (SDL)
- Google Maps API
- YouTube API
- MediaWiki API