BONDI 1.1 api에 대해 알아보기 앞서, api를 좀 더 잘 이해하기 위해 The BONDI API Design Patterns – Version 1.1 에 대해 알아보겠습니다.
1. Introduction
BONDI는 API들를 정의하고, 이 BONDI interface들은 WebIDL과 Documentation(doxygen과 유사하게)로 기술되어 있습니다.
BONDI Module 은 BONDI interface들로 구성되어 있으며, 확장자가 “.widl”인 하나의 파일로 기술됩니다.
이 Module은 앞으로도 증가할 것이기 때문에, WebIDl과 Documentaion을 어떻게 구성해야하는지에 대한 rule을 정의할 필요가 있습니다.
본 문서에서는 이 Rule에 대해 정의하고 있습니다.
2. WebIDL patterns
BONDI API는 WebIDL (W3C’s interface definition language)으로 기술되어 있습니다.
2.1. Error Handling
WebIDL에서는 methods, getters 그리고 setters에서 exception 과 exception시 전달되는 object의 발생이 가능합니다.
WebIDL exception은 상속구조를 가질 수 없습니다.
하지만 BONDI module에서는 각 module 마다 자신의 error interface를 가질 수 있습니다.
그래서 BONDI에서 계층적 error를 지원하기 위해서는 BONDI error interface를 사용하여야 합니다.
- BONDI WebIDL 은 Exception에 대해 정의하지 않는다.
- BONDI WebIDL의 모든 error interface는 BONDI generic error interface에서 상속받는다. GenericError는 ECMAScript Error에서 상속받는다.
- GenericError에서 상속받은 object interface는 BONDI의 함수, attribute getter, attribute setter를 통하여 인스턴스화 될 수 있다.
- Error object는 object의 prototype 및 constructor 그리고 GenericError object의 attribute인 “error code”에 의해 식별될 수 있어야 한다.
- Security와 관련된 error interface는 SecurityError에서 상속받으며, SecurityError는 GenericError에서 상속받는다.
- Error code 상수(constant)는
- 대문자로 정의된다.
- 접미사 “_ERROR”를 사용한다.
- 단어는 “_”로 사용하여 구분된다.
- DeviceAPIError interface 는 Common error code를 포함하며, GenericError에서 바로 상속받는다.
- Module 에서 정의하는 error 상수는 0 부터 시작된다.
- Common error code 는 10,000 – 19,999 구간에서 정의된다.
- Security 관련 error 는 20,000 – 29,999 구간에서 정의된다.
WebIDL definition
interface Error {
readonly attribute DOMString name;
readonly attribute DOMString message;
};
interface GenericError : Error {
readonly attribute unsigned short code;
};
interface DeviceAPIError : GenericError {
const unsigned short UNKNOWN_ERROR = 10000;
const unsigned short INVALID_ARGUMENT_ERROR = 10001;
const unsigned short NOT_FOUND_ERROR = 10002;
const unsigned short PENDING_OPERATION_ERROR = 10003;
const unsigned short IO_ERROR = 10004;
const unsigned short NOT_SUPPORTED_ERROR = 10005;
};
interface SecurityError : GenericError {
const unsigned short PERMISSION_DENIED_ERROR = 20000;
};
2.2. Asynchronicity
BONDI WebIDL에서 비동기 함수는
- 최소 2개의 parameter를 갖는다. 첫 번째는 SuccessCallback interface에서 상속받는 함수이며, 두 번째는 ErrorCallback interface에서 상속받는 함수이다.
- 비동기 함수는 에러를 발생시키지 않고, ErrorCallback를 통하여 에러를 전달한다.
- PendingOperation object를 리턴한다. 리턴값이 null이라면 비동기 함수가 이미 호출되었음을 의미한다.
- PendingOperation 은 object의 “cancel” 함수 호출을 통하여 비동기 함수의 실행을 취소할 수 있습니다.
- 이 “cancel” 함수는
- 동기 방식으로 동작한다.
- 항상 성공적으로 수행된다.
- 리턴값이 true 이면 이미 callback 함수가 호출되었음을 의미한다.
- false이면 성공적으로 취소되었음을 의미한다.
WebIDL definition
[Callback] interface SuccessCallback {
void onSuccess(in Object ob);
};
[Callback] interface ErrorCallback {
void onError(in Error error);
};
interface PendingOperation {
boolean cancel();
};
2.2.1. How to combine APIs with architecture and security principles?
BONDI API의 설계시 ” BONDI Architecture & Security”의 원칙을 반드시 만족시켜야 합니다.
“BONDI Architecture & Security” 률은 아래와 같다.
- BONDI의 security policy를 따르는 함수는 비동기 방식으로 동작한다.
- attribute는 security policy를 따르지 않는다.
2.3. Namespaces and interface structure
BONDI Module 은 BONDI interface들로 구성되어 있는데, 이 계층을 나타내기 위해 WebIDl의 “implements” keyword를 사용합니다.
예를들어
Window implements bondiObject;
으로 정의된 경우 bondi interface가 Window object의 property임을 나타냅니다.
module bondi {
interface bondi {
...
PendingOperation requestFeature (in RequestFeatureSuccessCallback successCallback,
in ErrorCallback errorCallback,
in DOMString name)
raises (DeviceAPIError, SecurityError);
...
};
interface bondiObject {
readonly attribute bondi bondi;
};
Window implements bondiObject;
};
module calendar {
interface CalendarManager {
...
...
};
interface Calendar {
...
...
};
interface CalendarManagerObject {
readonly attribute CalendarManager calendarManager;
};
bondi implements CalendarManagerObject;
};
2.4. Data records, supported property keys and filters
BONDI API는 data와 관련된 검색 연산을 수행합니다.
BONDI module과 interface는 검색시 통일된 방법으로 filter를 표현하고 있습니다.
ECMAScript는 object의 property를 동적으로 추가할 수 있는데, 이는 매우 유용한 확장 구조입니다..
반면 저장 가능한 object를 다루기는 어려워 집니다.
왜냐하면, 어떤 platform에서는 미리 정의된 property와 그 값에 대해서만 저장할 수 있기 때문입니다.
그래서 상호 운영성의 측면에서 최소한의 property set을 정의할 필요가 있습니다.
그 결과, 다음과 같은 범주로 property를 나누게 되었습니다.
- interoperable data-carrying properties,
- platform-specific data-carrying properties,
- application-specific data-carrying properties,
- administrative properties.
property를 이러한 범주로 나누기 위해서,
저장 가능한 정보를 담고 있는 property들은 접미사 ”Properties”가 붙는 interface로 구성되도록 하였습니다.
예를 들면, contact의 경우 다음과 같은 기본 interface를 갖도록 처음 설계되었습니다.
interface Address {
attribute DOMString country;
attribute DOMString postalCode;
};
interface Contact {
readonly attribute DOMString id;
attribute DOMString name;
attribute DOMString email;
attribute Address address;
};
contact interface의 property 중 name, email, address 는 contact의 정보를 담고 있습니다.
반면 id 는 contact 정보가 아닌 관리상의 정보를 담고 있으며 platform에서 값을 할당하기 때문에 읽기 전용 속성을 가지고 있습니다.
따라서 아래와 같이 property-set 을 나눌 수 있습니다.
interface ContactProperties {
attribute DOMString name;
attribute DOMString email;
attribute Address address;
};
interface Contact : ContactProperties {
readonly attribute DOMString id;
};
- contact의 정보를 담고 있는 property는 ContactProperties interface로 구성한다.
- Contact interface ContactProperties interface로 부터 상속받는다.
“interoperable data-carrying properties”는 XXXProperties interfaces에 속하며 모든 platform에서 사용 및 저장 가능하도록 구현되어야 하는 필수 property-set 입니다.
“platform-specific data-carrying properties”는 특정 platform에서만 사용 가능한 property 입니다.
“application-specific data-carrying properties”는 특정 application 에서만 사용 가능한 property 입니다.
XXX (XXXProperties 와 구별하기 위해) interface는 filter object를 생성할 때 사용됩니다.
그리고 지원하지 않는 filter object의 property는 구현부에서 무시해야 합니다.
<filter object의 생성 Rule>
- filter object는 XXX object의 JSON 형식으로 표현됩니다.
- filter interface는
- GenericFilter로 부터 상속받는다.
- XXX interface를 기반으로 하는 XXXFilter interface는 반드시 존재해야 한다.
- filter 연산의 결과 데이터는 아래 규칙에 의해 연산된다.
- filter object에 property가 나열되지 않았다면, 해당 property 의 모든 값 그리고 전체 데이터가 대상임을 의미한다.
- filter object에 포함된 property는 서로간에 SQL “AND”와 같은 연산방식으로 처리된다.
- filter object가 null이라면, 전체 데이터를 반환한다.
- 반환되는 result-set의 정렬 순서는 구현부에서 결정한다.
3. Architectural patterns
3.1. Versioning
BONDI interface는 앞으로도 계속 발전할 것이며, interface 들도 계속 수정도 될 것입니다.
앞으로 release될 버전은 method나 attribute가 추가되거나 삭제 또는 수정될 수 있습니다.
이 변경에 대처하기 위해 versioning model이 필요합니다.
BONDI API versioning은 API feature의 IRI 에 기반하여 정의되어 있습니다.
만약 feature의 기능이 변경되었다면, 새로운 IRI가 추가되어야 합니다.
3.2. API coverage by features
BONDI API는 사용자의 privacy 보호를 위해 security policy와 관련되어 있습니다.
몇 몇 API는 security 제한으로 접근이 되지 않을 수도 있고, 또 다른 API들은 해당 platform 이나 User Agent에서 유효하지 않을 수도 있습니다.
BONDI에서는 feature를 사용하여 API에 대한 접근 권한 제어를 하고 있습니다.
- 먼저 접근하려는 API들의 feature를 configuration 문서 (또는 프로그램적인 방법으로) 에 기술한다.
- 그리고 API의 접근요청이 오면, 접근에 대한 동의여부를 결정한다
이를 위해 모든 method, attribute, constant 는 적어도 하나의 feature에 속해야 합니다.
3.3. Feature-sets
Rich Web Application은 많은 BONDI API들를 사용합니다.
그리고 BONDI security model을 만족하기 위해 많은 feature를 configuration 문서 (또는 프로그램적인 방법으로)에 정의해야 합니다.
이는 Application 에 성능 저하를 줄 수 있으며, configuration 문서작성을 힘들게 합니다.
이를 해결하기 위해 BONDI에서는 feature-set을 정의합니다.
feature-set은 하나 이상의 feature를 포함하고 있습니다.
그리고 각 module은 적어도 하나 이상의 feature-set이 정의되어야 합니다.
festure-set은 module의 모든 feature를 포함할 수도 있습니다.