Specification and Automated Analysis of Inter-Parameter Dependencies in Web APIs

05/07/2020 ∙ by Alberto Martin-Lopez, et al. ∙ 0

Web services often impose inter-parameter dependencies that restrict the way in which two or more input parameters can be combined to form valid calls to the service. Unfortunately, current specification languages for web services like the OpenAPI Specification (OAS) provide no support for the formal description of such dependencies, which makes it hardly possible to automatically discover and interact with services without human intervention. In this article, we present an approach for the specification and automated analysis of inter-parameter dependencies in web APIs. We first present a domain-specific language, called Inter-parameter Dependency Language (IDL), for the specification of dependencies among input parameters in web services. Then, we propose a mapping to translate an IDL document into a constraint satisfaction problem (CSP), enabling the automated analysis of IDL specifications using standard CSP-based reasoning operations. Specifically, we present a catalogue of nine analysis operations on IDL documents allowing to compute, for example, whether a given request satisfies all the dependencies of the service. Finally, we present a tool suite including an editor, a parser, an OAS extension, a constraint programming-aided library, and a test suite supporting IDL specifications and their analyses. Together, these contributions pave the way for a new range of specification-driven applications in areas such as code generation and testing.

READ FULL TEXT VIEW PDF
POST COMMENT

Comments

There are no comments yet.

Authors

page 3

page 5

page 14

This week in AI

Get the week's most popular data science and artificial intelligence research sent straight to your inbox every Saturday.

1 Introduction

Web Application Programming Interfaces (APIs) allow systems to interact with each other over the network, typically using web services [21, 41]. Web APIs are rapidly proliferating as the cornerstone for software integration enabling new consumption models such as mobile, social, Internet of Things (IoT), or cloud applications. Many companies are also exposing their existing assets as private APIs, fostering reusability, integration, and innovation within the boundaries of their own companies [21, 22]. Popular API directories such as ProgrammableWeb [37] and RapidAPI [40] currently index over 22K and 10K web APIs, respectively, from multiple domains such as shopping, finances, social networks, or telephony.

Modern web APIs typically adhere to the REpresentational State Transfer (REST) architectural style, being referred to as RESTful web APIs [8]. RESTful web APIs are decomposed into multiple web services, where each service implements one or more create, read, update, or delete (CRUD) operations over a resource (e.g., an invoice in the PayPal API), typically through HTTP interactions. RESTful APIs are commonly described using languages such as the OpenAPI Specification (OAS) [34], originally created as a part of the Swagger tool suite [44], or the RESTful API Modeling Language (RAML) [39]. These languages are designed to provide a structured description of a RESTful web API that allows both humans and computers to discover and understand the capabilities of a service without requiring access to the source code or additional documentation. Once an API is described in an OAS document, for example, the specification can be used to generate documentation, code (clients and servers), or even basic automated test cases [44]. In this article, we focus on RESTful web APIs and OAS as the arguable standards for web integration. In what follows, we will use the terms RESTful web API, web API, or simply API interchangeably.

Web services often impose dependency constraints that restrict the way in which two or more input parameters can be combined to form valid calls to the service, we call these inter-parameter dependencies (or simply dependencies henceforth). For instance, it is common that the inclusion of a parameter requires or excludes—and therefore depends on—the use of some other parameter or group of parameters. As an example, the documentation of the Twilio API [47] states that, when sending an SMS, either the body parameter or the media_url parameter must be set, but not both at the same time. Similarly, the documentation of the QuickBooks payments API [38] explains that, when creating a credit card, at least one of the parameters region or postalCode must be provided, although both of them are declared as optional.

Current specification languages for RESTful web APIs such as OAS and RAML provide little or no support at all for describing dependencies among input parameters. Instead, they just encourage to describe such dependencies as a part of the description of the parameters in natural language, which may result in ambiguous or incomplete descriptions. For example, the Swagger documentation states111https://swagger.io/docs/specification/describing-parameters/OpenAPI 3.0 does not support parameter dependencies and mutually exclusive parameters. (…) What you can do is document the restrictions in the parameter description and define the logic in the 400 Bad Request response”. The lack of support for dependencies means a strong limitation for current specification languages, since without a formal description of such constraints is hardly possible to interact with the services without human intervention. For example, it would be extremely difficult to automatically generate test cases for the APIs of Twilio or QuickBooks without an explicit and machine-readable definition of the dependencies mentioned above. The interest of industry in having support for these types of dependencies is reflected in an open feature request in OAS entitled “Support interdependencies between query parameters”, created in January 2015 with the message shown below. At the time of writing this paper, the request has received over 260 votes, and it has received 55 comments from 33 participants222https://github.com/OAI/OpenAPI-Specification/issues/256.

“It would be great to be able to specify interdependencies between query parameters. In my app, some query parameters become “required” only when some other query parameter is present. And when conditionally required parameters are missing when the conditions are met, the API fails. Of course I can have the API reply back that some required parameter is missing, but it would be great to have that built into Swagger.”

This feature request has fostered an interesting discussion where the participants have proposed different ways of extending OAS to support dependencies among input parameters. However, each approach aims to address a particular type of dependency and thus show a very limited scope. Addressing the problem of modelling and validating input constraints in web APIs should necessarily start by understanding how dependencies emerge in practice. Inspired by this idea, in a previous paper we conducted a thorough study on the presence of inter-parameter dependencies in industrial web APIs [26]. For that purpose, we reviewed more than 2.5K operations from 40 real-world RESTful APIs from different application domains. As expected, we found that input dependencies are the norm, rather than the exception, with 85% of the reviewed APIs having some kind of dependency among their input parameters. More importantly, as the main outcome of our study, we presented a catalogue of seven types of dependencies consistently found in RESTful web APIs. These findings, and specifically the catalogue of dependencies (described in Section 2), serve as the starting point for this work.

In this article, we first present a domain-specific language for the specification of inter-parameter dependencies in web APIs called Inter-parameter Dependency Language (IDL). Second, we present an approach for the automated analysis of IDL specifications using constraint programming. In particular, we present a general-purpose mapping showing how to translate an IDL specification into a constraint satisfaction problem (CSP). Then, we present a catalogue of nine analysis operations of IDL specifications and show how they can be automated using standard constraint programming reasoning operations. For example, given an IDL specification one may be interested to know if it includes any inconsistencies like parameters that cannot be selected (dead parameters) or whether a given call to the API satisfies all the dependencies. Our approach is supported by several tools including an (Eclipse) editor, a parser, an OAS extension (called IDL4OAS), and a constraint-programming aided library supporting the automated analysis of IDL specifications. These tools were heavily validated using standard testing techniques resulting in a test suite composed of 178 test cases, which will hopefully facilitate future extensions and alternative implementations.

The contributions reported in this paper prepare the ground for a new range of specification-driven applications in web APIs. For example, an API gateway supporting the automated analysis of IDL could automatically reject requests violating any dependencies, without even redirecting the call to the corresponding service, saving time and user quota. Also, test case generators supporting the automated analysis of IDL could automatically generate valid test cases (those satisfying all the dependencies among input parameters) rather than using brute force or writing specific input grammars for each API under test. Code generators could benefit from IDL as well. For instance, automatically-generated clients could include built-in assertions to deal with invalid input combinations, preventing input-validation failures. Analogously, interactive API documentations could be enriched with analysis capabilities to detect invalid calls even before invoking the API. The range of new applications is promising.

This paper is structured as follows: Section 2 presents the catalogue of dependency patterns found in our systematic review of real-world APIs. Section 3 introduces the syntax of IDL using examples. Section 4 describes our approach for the automated analysis of IDL specifications. Our tool suite is presented in Section 5. Section 6 describes the evaluation of our approach. Section 7 describes the possible threats to validity and how these were mitigated. The related work is discussed in Section 8. Finally, Section 9 concludes the paper and presents future lines of research.

2 Catalogue of Dependencies

The contributions presented in this paper are built on the findings of a previous study by the authors on the presence of inter-parameter dependencies in industrial RESTful Web APIs [26]. For the sake of understandability and to make our paper self-contained, we next summarise those results more relevant for this article, and redirect the interested reader to the original paper for further details.

(a) Dependency types.
(b) Occurrences in APIs
Figure 3: Distribution of dependencies by type and percentage of APIs.

In our previous study, we reviewed more than 2.5K operations from 40 real-world RESTful APIs including popular APIs such as those of YouTube, Google Maps, Amazon S3, and PayPal. The results of the study showed that dependencies are extremely common and pervasive—they appear in 85% of the APIs under study (34 out of 40) across all application domains and types of operations. Specifically, we identified 633 dependencies among input parameters in 9.7% of the API operations analysed (248 out of 2,557). The collected data helped us to characterise dependencies identifying their most common shape—dependencies in read operations involving two query parameters—, but also exceptional cases such as dependencies involving up to 10 parameters and dependencies among different types of parameters, e.g., header and body parameters. More importantly, we classified the inter-parameter dependencies identified into seven general types, described below.

Before going in depth into each type of dependency, a number of considerations must be taken into account. First, for the sake of simplicity, dependencies are described using single parameters. However, all dependencies can be generalised to consider groups of parameters using conjunctive and disjunctive connectors. Second, dependencies can affect not only the presence or absence of parameters, but also the values that they can take. In what follows, when making reference to a parameter being present or being absent, it could also mean a parameter taking a certain value. Finally, when introducing each dependency type we will make reference to Figure 3, which shows the distribution of dependencies by type (Figure (a)a) and the percentage of subject APIs including occurrences of each dependency type (Figure (b)b). Next, we describe the seven types of dependencies found in our study, including examples.

Requires. The presence of a parameter in an API call requires the presence of another parameter , denoted as . As previously mentioned, and can be generalised to groups of parameters and parameter-value relations, e.g., . Based on our results, this is the most common type of dependency in web APIs, representing 35% of all the dependencies identified in our study (Figure (a)a), and being present in 47.5% of the subject APIs (Figure (b)b). As an example, in the GitHub API [17], when creating a card in a project, if the parameter content_id is present, then content_type becomes required, i.e., content_id content_type. Similarly, in the Bing Maps API [4], when calculating the distance of a set of routes, if the parameter startTime is used, then the parameter travelMode must be set to ‘driving’, i.e., startTime travelMode=driving.

Or. Given a set of parameters , one or more of them must be included in the API call, denoted as . As illustrated in Figure 3, this type of dependencies represent only 3% of the dependencies identified in the subject APIs. Interestingly, however, we found that more than one fourth of the APIs (27.5%) included some occurrence of this type of dependency, which suggests that its use is fairly common in practice. As an example, in the Google Maps Places API [18], when searching for places, both query and type parameters are optional, but at least one of them must be used, i.e., query, type. Similarly, in the NationBuilder API [31], when creating a blog post, it is possible to show different contents on the index page and the full post page by using the parameters contentbeforeflip and contentafterflip, respectively, but at least one of them must be set, i.e., contentbeforeflip, contentafterflip.

OnlyOne. Given a set of parameters , one, and only one of them must be included in the API call, denoted as . As observed in Figure 3, this group of dependencies represent 17% of all the dependencies identified, and they appear in almost half of the APIs under study (47.5%). Among others, we found that this type of dependency is very common in APIs from the category media, where a resource can be identified in multiple ways, e.g., a song can be identified by its name or by its ID, and only one value must be typically provided. For example, in the Last.fm API [24], when getting the information about an artist, this can be identified with two possible parameters, artist or mbid, and only one must be used, i.e., artist, mbid. Similarly, in the GeoNames API [16], when searching for places, they must be filtered using one, and only one of the parameters q, name and name_equals, i.e., q, name, name_equals.

Figure 4: ZeroOrOne dependency in the YouTube API.

AllOrNone. Given a set of parameters , either all of them are provided or none of them, denoted as . Very similarly to the Or dependency type, only 6% of the dependencies found belong to this category, nonetheless, they are present in about one third of the APIs under study (30%). In the Yelp API [52], for example, when searching for events, the location can optionally be specified with two parameters, latitude and longitude, and they must be used together, i.e., latitude, longitude. In the Bing Web Search API [3], when using the Accept-Language header, the cc (country code) query parameter must be specified too, and vice versa, i.e., Accept-Language, cc.

ZeroOrOne. Given a set of parameters , zero or one can be present in the API call, denoted as . Figure 3 reveals that this dependency type is common both in terms of the number of occurrences (18% of the total) and the number of APIs including it (47.5%). As an example, in the Flickr API [9], when fetching photos from the user’s contacts, either one or multiple photos can be obtained by using the parameters single_photo or count, respectively, but they cannot be used together (if none is used, all photos are returned), i.e., single_photo, count. Another example is found in the search operation of the YouTube API [54], where it is possible to filter results with four optional but mutually exclusive parameters, as depicted in Figure 4. This dependency can be expressed as forContentOwner, forDeveloper, forMine, relatedToVideoId.

Arithmetic/Relational. Given a set of parameters , they are related by means of arithmetic and/or relational constraints, e.g., . As shown in Figure 3, this type of dependency is the most recurrent across the subject APIs, being present in half of them. Moreover, 17% of the dependencies found are of this type. As an example, in the Twitter API [53], when searching for tweets, the max_id parameter must be greater than or equal to the since_id parameter, otherwise no tweets will be returned, i.e., max_id since_id. In the payments API Forte [10], when creating a merchant application, this can be owned by several businesses, in which case the sum of the percentages cannot be greater than 100, i.e., owner.percentage owner2.percentage owner3.percentage owner4.percentage 100.

Figure 5: Complex dependency present in the GET /venues/search operation of the Foursquare API.

Complex. These dependencies involve two or more of the types of constraints previously presented. Based on our results, they are typically formed by a combination of Requires and OnlyOne dependencies. As illustrated in Figure 3, we found 4% of complex dependencies, being present in 7.5% of the subject APIs. For example, in the Stripe API [42], when retrieving the information about an upcoming invoice, if subscription_trial_end is present, then one of subscription_items or subscription must be set too, i.e., subscription_trial_end subscription_items, subscription. Figure 5 shows an extract of the documentation of the search operation in the Foursquare API [11]. As illustrated, if radius is used, then either intent is set to ‘browse’ or intent is set to ‘checkin’ and categoryId or query are present too, i.e., radius intent=browse, intent=checkin (categoryId query.

3 Inter-parameter Dependency Language

In this section, we present Inter-parameter Dependency Language (IDL), a textual domain-specific language for the specification of dependencies among input parameters in web APIs. Specifically, IDL is designed to express the seven types of inter-parameter dependencies identified in our study on real-world APIs, and described in the previous section. For the design of the language, we took inspiration from the input format of the combinatorial testing tool Pairwise Independent Combinatorial Testing (PICT) [36], by Microsoft, where constraints among input parameters can be defined using invariants, conditional definitions (if/then/else), logical operators and relational operators.

It is worth mentioning that IDL focuses on the definition of dependencies among parameters, but not in the definition of the parameters themselves. This is because IDL is specifically designed to be easily integrated into API specification languages such as OAS or RAML, where parameters are specified in different ways. Thus, in what follows, we simply assume that each parameter has a name and a domain.

A simplified version of the grammar of the language is provided in Listing 1—the full version is available as a part of the implementation of IDL [19] and on the supplemental material provided with this article [43].

1Model:˙  Dependency*;
2Dependency:˙    RelationalDependency | ArithmeticDependency |
3    ConditionalDependency | PredefinedDependency;
4RelationalDependency:˙  Param RelationalOperator Param;
5ArithmeticDependency:˙  Operation RelationalOperator DOUBLE;
6Operation:˙  Param OperationContinuation |
7  '(' Operation ')' OperationContinuation?;
8OperationContinuation:˙  ArithmeticOperator (Param | Operation);
9ConditionalDependency:˙  'IF' Predicate 'THEN' Predicate;
10Predicate:˙    Clause ClauseContinuation?;
11Clause:˙    (Term | RelationalDependency | ArithmeticDependency˙    | PredefinedDependency) | 'NOT'? '(' Predicate ')';
12Term:˙    'NOT'? (Param | ParamValueRelation);
13Param:˙  ID | '[' ID ']';
14ParamValueRelation:˙  Param '==' STRING('|'STRING)* |
15  Param 'LIKE' PATTERN_STRING | Param '==' BOOLEAN |
16  Param RelationalOperator DOUBLE;
17ClauseContinuation:˙  ('AND' | 'OR') Predicate;
18PredefinedDependency:˙  'NOT'? ('Or' | 'OnlyOne' | 'AllOrNone' |
19  'ZeroOrOne') '(' Clause (',' Clause)+ ')';
20RelationalOperator:˙  '<' | '>' | '<=' | '>=' | '==' | '!=';
21ArithmeticOperator:˙  '+' | '-' | '*' | '/';
Listing 1: Simplified grammar of IDL.

The key elements of the language are terms and predicates. Both of them can evaluate to true or false. A term is an atomic element of the language and can be represented by: (1) a parameter’s name (e.g., p1) being evaluated as true if the parameter is set (regardless of the value), or false otherwise; or (2) a parameter-value relation, evaluated as true if the parameter is selected and satisfies the relation. This relation can be defined using standard relational operators (e.g., p1>=100) or a wild card match—using the operator LIKE—if the parameter is a string, with ’*’ meaning zero or more characters and ’?’ meaning one character (e.g., p3 LIKE ‘test_*’). A predicate is a combination of one or more terms and dependencies joined by the logical operators NOT, AND, and OR. Parentheses are allowed in order to specify the operator priority. In what follows, we describe the IDL notation of each type of dependency.

Requires. This type of dependency is expressed as “IF predicate THEN predicate;”, where the first predicate is the condition and the second is the consequence. The following listing shows two examples. Dependency in line 2, for instance, indicates that invocations including the parameters p1 and p2 should not include p3 nor p4, otherwise the call would be invalid.

1IF p1 THEN p2=='A';
2IF p1 AND p2 THEN NOT (p3 OR p4);

Or. This type of dependency is expressed using the keyword “Or” followed by a list of two or more predicates placed inside parentheses: “Or(predicate, predicate [, ...]);”. The dependency is satisfied if at least one of the predicates evaluates to true. Two examples follow. Dependency in line 1, for instance, specifies that valid invocations should include at least one of the parameters p1, p2 or p3.

1Or(p1, p2, p3);
2Or(p1, p3 AND p5, p6=='B');

OnlyOne. These dependencies are specified using the keyword “OnlyOne” followed by a list of two or more predicates placed inside parentheses: “OnlyOne(predicate, predicate [, ...]);”. The dependency is satisfied if one, and only one of the predicates evaluates to true. Examples of this dependency are shown below. The dependency in line 1, for example, indicates that valid invocations should include either the parameter p1 or the parameter p2 with value ‘B’, but not both at the same time.

1OnlyOne(p1, p2=='B');
2OnlyOne(p1 OR p2, p3 AND (p4 OR p5));

AllOrNone. This type of dependency is specified using the keyword “AllOrNone” followed by a list of two or more predicates placed inside parentheses: “AllOrNone(predicate, predicate [, ...]);”. The dependency is satisfied if either all the predicates evaluate to true, or all of them evaluate to false. The dependency in line 1 below, for instance, indicates that valid calls are those including either the parameter p1 and p2 with value true, or conversely, those not including the parameter p1 and not including p2 with value true.

1AllOrNone(p1, p2==true);
2AllOrNone(p1 AND p2, p3 LIKE 'test_*' OR p4<10);

ZeroOrOne. These dependencies are specified using the keyword “ZeroOrOne” followed by a list of two or more predicates placed inside parentheses: “ZeroOrOne(predicate, predicate [, ...]);”. The dependency is satisfied if none or at most one of the predicates evaluates to true. Two examples follow. Line 2, for instance, specifies that valid invocations must meet zero or one (but not both) of the two conditions between parentheses: (1) including the parameter p1, or (2) including the parameter p2 with a value less than or equal to 100.

1ZeroOrOne(p1, p2, p3, p4);
2ZeroOrOne(p1, p2<=100);

Arithmetic/Relational. Relational dependencies are specified as pairs of parameters joined by any of the following relational operators: ==, !=, <=, <, >= or > (see examples in lines 1 and 2 below). Arithmetic dependencies relate two or more parameters using the operators +, - , *, / followed by a final comparison using a relational operator. Lines 3 and 4 of the following listing show examples of arithmetic dependencies.

1p1 < p2;
2p1 != p2;
3p1 + p2 - p3 * p4 == 100;
4p1 * p2 / ((p3 - p4) * p5) < 176.89;

Complex. These dependencies are specified as a combination of the previous ones since, as previously mentioned, predicates can contain other dependencies. As an exception to this rule, predicates cannot include Requires dependencies to avoid over-complicated specifications (such dependencies can be expressed in simpler ways). The following listing shows some examples of complex dependencies. Dependency in line 1 combines four different types of dependencies: Requires, ZeroOrOne, OnlyOne and Relational.

1IF p1 THEN ZeroOrOne(p2, OnlyOne(p3, p4>p5));
2AllOrNone(p1+p2<100, Or(p3=='A', Or(p4, p5>p6));

It is worth making a few general clarifications about the language regarding dependencies Or, OnlyOne, AllOrNone and ZeroOrOne. These are not strictly necessary, as they could be translated to several Requires dependencies. However, they are provided as syntactic sugar to make specifications succinct and self-explanatory. An example is given in the following IDL excerpt (lines 1-3). Secondly, they cannot contain negated elements within their parentheses, since such constraints can be expressed in simpler ways (lines 5-6). Finally, they can optionally be preceded by the keyword “NOT” to negate the meaning of the constraint (see line 8 below for an example).

1AllOrNone(p1, p2);   // Equivalent to 1) and 2):
2IF p1 THEN p2;       // 1)
3IF p2 THEN p1;       // 2)
4
5Or(p1, NOT p2);      // Invalid dependency
6IF p2 THEN p1;       // Equivalent to line 5
7
8NOT OnlyOne(p1, p2); // Valid negated dependency

Listing 2 depicts the IDL specification of the Google Maps Places API [18]. It comprises seven operations, four of which have dependencies. The API has eight dependencies in total, including six out of the seven types of dependencies supported in IDL (all of them except the complex ones), namely:

  • Line 2: If the parameter radius is used, then rankby cannot be set to ‘distance’, and vice versa.

  • Line 3: If the parameter rankby is set to ‘distance’, then at least one of the following parameters must be present: keyword, name or type.

  • Line 4: The parameter maxprice must be greater than or equal to minprice.

  • Line 7: Either both location and radius are used, or none of them.

  • Line 8: query and type are both optional parameters, but at least one of them must be used.

  • Line 9: Equal to line 4.

  • Line 12: One, and only one of the parameters maxheight and maxwidth must be used.

  • Line 15: If the parameter strictbounds is used, then both location and radius must be used as well.

1// Operation: Search for places within specified area:
2ZeroOrOne(radius, rankby=='distance');
3IF rankby=='distance' THEN keyword OR name OR type;
4maxprice >= minprice;
5
6// Operation: Query information about places:
7AllOrNone(location, radius);
8Or(query, type);
9maxprice >= minprice;
10
11// Operation: Get photo of place:
12OnlyOne(maxheight, maxwidth);
13
14// Operation: Automcomplete place name:
15IF strictbounds THEN location AND radius;
Listing 2: IDL specification of Google Maps Places API.

4 Automated Analysis

The analysis of IDL deals with the extraction of information from IDL specifications. For example, given an IDL specification, we might be interested to know whether it contains errors (e.g., inconsistent dependencies) or whether a given API call is valid, i.e., it meets all the constraints defined in the specification. Performing these analyses manually is hardly possible in practice.

In what follows, we present our approach for the automated analysis of IDL specifications using constraint programming. In particular, we first present the formal semantics of IDL by explaining how IDL specifications can be mapped to a constraint satisfaction problem (CSP). Then, we present a catalogue of nine analysis operations of IDL specifications and show how they can be automated using standard constraint programming reasoning operations.

4.1 Formal Semantics of IDL

The primary objective of formalising IDL is to establish a sound basis for the automated support. Following the formalisation principles defined by Hofstede et al. [45], we follow a transformational style by translating IDL specifications to a target domain suitable for the automated analysis (Primary Goal Principle). Specifically, we propose translating IDL specifications to a CSP that can be then analysed using state-of-the-art constraint programming tools. A similar approach was followed by the authors to automate the analysis of feature models [2] and service level agreements [30, 29].

A CSP is defined as a 3-tuple composed of a set of variables , their domains and a number of constraints . A solution for a CSP is an assignment of values to the variables in from their domains in so that all the constraints in are satisfied.

Mapping from IDL to CSP
API Parameters CSP Mapping
[Parameters]
IDL Element CSP Mapping
Terms: map(T) [Parameter]
   

[Parameter-Value Relation]
   
Predicates: map(P) [Term]    
[Dependency]    

[Term AND Predicate]
    AND

[Term OR Predicate]
    OR

[NOT Predicate]
   NOT

Dependencies: map(D)
[Requires]
   IF THEN

[Or]
   

[OnlyOne]
   

[AllOrNone]
   

[ZeroOrOne]
   


[Relational Dependency]
   

[Arithmetic Dependency]
   
        
Table I: IDL to CSP mapping

Table I describes the mapping from IDL to CSP. The first row of the table depicts how each input parameter is mapped to CSP variables, domains and constraints. Recall that both the name and domain of each parameter should be taken from the API specification (c.f. and function). For each parameter, two CSP variables are created: (1) one representing the parameter itself (c.f. ), and (2) a Boolean variable to express whether the parameter is set or not (c.f. ). Optionally, we may also get information from the specification about whether each parameter is required (mandatory) or not. If a parameter is required (i.e., it must be present in all API calls), the constraint is added to the set of constraints . The second and third rows of the mapping in Table I express how the terms are mapped to a CSP. Every time a parameter is found in a predicate, it must be checked whether the parameter is present in the API request. If so, it will evaluate to true, otherwise it will evaluate to false (c.f. from the second row of the table). In the case of parameters having a relational condition with a value, it must also be checked that the parameter satisfies such condition (c.f. third row of the table). Finally, predicates and dependencies are defined recursively using the function , where is either a term, a predicate or a dependency. Exceptionally, relational and arithmetic dependencies are only evaluated if all the involved parameters are present in the API request (c.f. last two rows in Table I).

1V =  radius, radiusSet, rankby, rankbySet, keyword,
2      keywordSet, name, nameSet, type, typeSet,
3      maxprice, maxpriceSet, minprice, minpriceSet    
4
5D =  int, Boolean, string, Boolean, string, Boolean,
6      string, Boolean, string,  Boolean, int, Boolean,
7      int, Boolean                                    
8
9C = //ZeroOrOne(radius, rankby=='distance');
10    ((radiusSet==true (rankbySet==true AND˙    rankby==distance) AND ((rankbySet==true AND˙    rankby==distance) radiusSet==true)) OR˙    ((radiusSet==true) AND (rankbySet==true˙    AND rankby==distance))) AND˙    //IF rankby=='distance' THEN keyword OR name OR
11    //   type;
12    ((rankbySet==true AND rankby==distance)
13    ((keywordSet==true) OR (nameSet==true) OR˙    (typeSet==true))) AND˙    //maxprice >= minprice;
14    (((maxpriceSet==true) AND (minpriceSet==true)) 
15    (maxprice  minprice))                             
Listing 3: CSP of Search operation in Listing 2.

As an example, Listing 3 shows the resulting CSP obtained as a result of applying the proposed mapping to the IDL specification of the Search operation in the Google Maps Places API, specified in Listing 2 (lines 1-4). Analogously, Listings 4 and 5 depict the CSP constraints derived from the Query and Get operations in Listing 2, respectively (lines 6-9 and 11-12).

1C = //AllOrNone(location, radius);
2    ((locationSet==true  radiusSet==true) AND˙    (radiusSet==true  locationSet==true) AND˙    (locationSet==true radiusSet==true) AND˙    (radiusSet==true$\implies$$\neg$locationSet==true)) AND˙    //Or(query, type);
3    (querySet==true OR typeSet==true) AND˙    //maxprice >= minprice;
4    (((maxpriceSet==true) AND (minpriceSet==true)) 
5    (maxprice  minprice))                             
Listing 4: Constraints of Query operation in Listing 2.
1C = //OnlyOne(maxheight, maxwidth);
2   ((maxheightSet==true$\implies$$\neg$maxwidthSet==true) AND˙   (maxwidthSet==true$ \implies$$\neg$maxheightSet==true))             
Listing 5: Constraints of Get operation in Listing 2.

4.2 Analysis Operations

In this section, we propose a catalogue of nine analysis operations on IDL specifications. These operations leverage the formal description of the dependencies using IDL to extract helpful information such as identifying inconsistencies or checking whether an API call is valid or not. Analogous analysis operations have been defined in the context of the automated analysis of feature models [2] and service level agreements [30, 29]. We may remark that it is not our intention to propose an exhaustive set of analysis operations as that would exceed the scope of this article.

For the description of the operations in CSP, we will refer to the input IDL specification IDL and the list of parameters from the API specification P. Additionally, we will use the following auxiliary operations:

  • map(IDL,P). This operation translates an input IDL specification IDL and the list of parameters P from the API specification to a CSP following the mapping described in Section 4.1.

  • solve(CSP). This standard CSP-based operation returns a random solution for the input CSP (if any).

  • solveAll(CSP). This standard CSP-based operation returns all the solutions of the input CSP (if any).

  • filter(CSP,L). This operation takes as input a CSP and a list L of pairs variable-value to be set, , and returns the input CSP with additional constraints setting each variable in L, , to its corresponding value , i.e., .

In what follows, for each operation, we provide a name, a description, an example, and an explanation of how it is mapped to a CSP.

Consistent specification. This operation receives as input an IDL specification and the list of parameters included on it, and returns a Boolean indicating whether the specification is consistent or not. An IDL specification is consistent if there exists at least one request satisfying all the dependencies of the specification. Inconsistent specifications are obviously undesired and therefore automating their detection can be very helpful. This operation can be translated to a CSP as follows:

Dead parameter. This operation takes as input an IDL specification, the list of parameters in the specification, and the name of a parameter, and it returns a Boolean indicating whether the parameter is dead or not. A parameter is dead if it cannot be included in any valid call to the service. Dead parameters are caused by inconsistencies in the specification or the design of the service. They may be hard to detect when the inconsistency is caused by several inter-related dependencies. For example, in the following IDL specification, the parameter p1 is dead since both constraints cannot be satisfied at the same time.

1IF p1 THEN p2;
2OnlyOne(p1, p2);

Given an input parameter p, this operation can be automated by setting the CSP variable representing the presence of p to true () and checking whether the problem has at least one solution. If there is no solutions, it means that p is dead, namely:

False optional. This operation assumes that the specification of each parameter indicates, as in OAS, whether the parameter is required (i.e., it must be included in every service request) or optional. This operation takes as input an IDL specification, its parameters, and the name of a parameter specified as optional, and returns a Boolean indicating whether the parameter is false optional or not. A parameter is false optional if it is required (i.e., it must be included in all API calls to satisfy inter-parameter dependencies) despite being defined as optional. False optional parameters should be avoided since they give the user a wrong idea of the domain. For example, suppose that the parameter p1 is defined as mandatory (e.g., ‘‘required’’: true in OAS) and p2 is declared as optional (‘‘required’’: false). The constraint “IF p1 THEN p2” in IDL would make p2 a false optional parameter.

Given an input parameter specified as optional p, this operation can be automated setting the CSP variable representing the presence of p to false () and checking whether the problem has at least one solution. If it has no solutions, p is false optional. Note that the input IDL specification should be consistent, otherwise all parameters would be classified as false optional. This operation can be translated to a CSP as follows:

Valid specification. This operation receives as input an IDL specification and the list of parameters included on it, and returns a Boolean indicating whether the specification is valid or not. An IDL specification is valid if it is consistent (i.e., there exists at least one request satisfying all the dependencies of the specification) and it does not contain any dead or false optional parameters. This operation may be helpful to easily detect errors when editing service specifications. This operation can be translated to a CSP as follows:

Valid request. This operation takes as input an IDL specification, the full list of parameters from the API specification, and a service request (i.e., a list of parameters and their values) and returns a Boolean indicating whether the request is valid or not. A service request is valid if it satisfies all the dependencies of the IDL specification. This operation may be helpful for the early detection of invalid calls to the system. For example, an API gateway supporting this operation could detect invalid calls without the need to redirect the request to the service, providing faster responses and reducing the consumption of user quota. For example, the following is a valid request for the IDL specification depicted in Listing 6 : {p1=2,p2=5}.

1Or(p1, p2 AND p3);
2OnlyOne(p2, p3);
Listing 6: Valid IDL specification.

Let R be an input request, i.e., a list of parameters and their respective values. This operation can be translated to a CSP by (1) setting the CSP variables related to each parameter to the value indicated in R, (2) setting the CSP variables related to the presence of the parameters in R to true (), (3) setting the CSP variables related to the parameters not included in R to false ( where ), and (4) checking whether the problem has at least one solution. If it has no solutions, it means that the request is not valid, namely:

Valid partial request. This operation is analogous to the previous one but the input request is partial or incomplete, meaning that some other parameters should still be included to make it a full valid request. This operation returns a Boolean indicating whether the partial request is valid. A partial request is valid if it does not include any contradiction, i.e., it can be extended with new parameters to become a valid request. This operation may be helpful for the early detection of inconsistencies. For example, an interactive API documentation supporting this operation could warn the user about inconsistencies as soon as a dependency is violated, without having to wait until constructing the full request.

Let S be a partial input request. This operation can be specified as a CSP as follows:

All requests. This operation receives as input the IDL specification of an API operation and the list of parameters from the API specification, and returns the list of all the possible requests to the service operation. As a precondition, all the parameters should have a discrete domain. Variants of this operation could be easily defined using standard combinatorial testing techniques, e.g., generate a list of requests that includes all the possible combinations of t parameters (t-wise testing [32]). This operation can be automated searching all the solutions of the corresponding CSP, namely:

Number of requests. This operation also requires all the parameters to have a discrete domain. It takes as input the IDL specification of a service operation and the list of parameters from the API specification, and returns the total number of possible requests to the operation. This operation can be helpful to understand the size of the input space of a service. A large number of potential requests could indicate that the operation is too complex and that some refactoring is needed. This operation can be translated to CSP by simply getting the cardinality of the set of solutions, as shown below. It is worth mentioning, however, that CSP solvers often provide specific operations to calculate the number of solutions of a CSP more efficiently.

Random request. This operation receives as input the IDL specification of an API operation and the list of parameters from the API specification, and returns a random valid request for the operation. This operation, in combination with test data generators, may be useful for random testing of services, or as an initial step for the generation of more sophisticated test cases using search-based techniques, for example. This operation can be automated by translating the IDL specification to a CSP and finding a random solution, namely:

5 Tooling Support

As a part of our contribution, we provide a set of tools supporting the specification and analysis of inter-parameter dependencies in web APIs, including an editor of IDL specifications, an extension for the OAS language and an analysis library supporting the integration of our approach into any external project. Together, these components make our work readily applicable in practice and provide a reference implementation for future contributions on the topic.

5.1 IDL Editor and Parser

We implemented IDL using Xtext [50], a popular framework for the development of programming languages and DSLs. Xtext takes a grammar as input and generates a complete set of tools as output, including a linker, a compiler, a parser and a fully-fledged editor supporting features such as code completion, type checking, syntax coloring and validation. A simplified version of the IDL grammar is provided in Listing 1, the full version is available as a part of the implementation of IDL [19] (and also on the supplemental material provided with this article [43]). Figure 6 depicts a screenshot of the editor, showing some of its capabilities: code completion, syntax coloring and error checking. The editor is based on Eclipse, but is compatible with any web browser or IDE supporting the Language Server Protocol [25].

Figure 6: IDL Editor.

5.2 IDL4OAS: An OAS Extension

In order to foster the adoption of our approach, we propose an extension of OAS for the specification of inter-parameter dependencies using IDL. We call this extension IDL4OAS. An OAS document describes a REST API in terms of the elements it comprises, namely paths, operations, resources, request parameters and responses. OpenAPI provides a way to add extra information that may not be supported natively. This information is included in custom properties that start with “x-”, called extensions. IDL4OAS is an OAS extension that allows to specify a set of IDL dependencies for each API operation. An extra property called “x-dependencies” must be added at the operation level, including the set of dependencies among the input parameters of the operation. Listing 7 shows an excerpt of an OAS document extended with IDL4OAS, corresponding to the Search operation from the Google Maps Places API (see Listing 2).

1paths:˙ /search:˙ get:˙ parameters:˙ - name: radius [...]
2      - name: rankby [...]
3      - name: keyword [...]
4      - name: name [...]
5      - name: type [...]
6      - name: minprice [...]
7      - name: maxprice [...]
8      - [...]
9      [...]
10      x-dependencies:˙ - ZeroOrOne(radius, rankby=='distance');
11      - IF rankby=='distance' THEN keyword OR name OR type;
12      - maxprice >= minprice;
Listing 7: OAS document of the search operation from the Google Maps Places API extended with IDL4OAS.

As illustrated, the property “x-dependencies” has been added to the “GET /search” operation. This property is actually an array of elements, where each element represents a single dependency, therefore they must be preceded by hyphens, following the YAML syntax.

5.3 IDLReasoner: An Analysis Library

In this section, we present IDLReasoner, a CSP-based Java library that allows to programmatically analyse IDL documents. Specifically, IDLReasoner translates input IDL specifications to CSPs using MiniZinc [27], a constraint solving language designed for modeling optimization problems in a high-level, solver-independent way. This allows IDLReasoner to be used with any CSP solver supporting MiniZinc as an input format.

Figure 7 shows the high-level architecture of IDLReasoner, using a UML component diagram. The library comprises three main components: the MiniZincMapper, which translates variables from the API specification and dependencies from IDL to MiniZinc, and manipulates the resulting MiniZinc file accordingly for each analysis operation; the Resolutor, which performs the calls to the selected CSP solver; and the Analyzer, which leverages the MiniZincMapper and the Resolutor components to execute the nine analysis operations from the catalogue.

IDLReasoner works as follows: the Analyzer takes three elements as input, namely, an IDL document, an API specification (e.g., OAS) and the API operation where the dependencies are present (e.g., “GET /search”). First, the MiniZincMapper transforms the API operation parameters, their domains and the IDL dependencies to a MiniZinc file, representing a CSP. Parameters and their domains are mapped by the VariableMapper component, and dependencies are mapped to constraints by the ConstraintMapper component. Then, when an analysis operation is invoked in the Analyzer component (e.g., valid specification), the MiniZincMapper manipulates the CSP file accordingly and the Resolutor calls the CSP solver on the manipulated file. IDLReasoner supports the nine analysis operations explained in Section 4.2. It is worth mentioning that IDLReasoner supports both IDL and OAS documents separately, as well as OAS documents including the specification of dependencies with IDL4OAS.

IDLReasoner is developed with extensibility in mind. It can be extended to multiple operating systems, web API specification languages and CSP solvers. At the time of writing this article, IDLReasoner supports Windows, OAS (and IDL4OAS), and a range of CSP solvers compatible with MiniZinc including Chuffed [6] and Gecode [15].

Figure 7: High-level architecture of IDLReasoner.

6 Evaluation

For the evaluation of our approach, we aim to answer two main research questions (RQs), namely:

  • RQ1 - Expressiveness. Is IDL expressive enough to model inter-parameter dependencies in real-world web APIs? As previously mentioned, IDL lies on strong foundations since it is based on the dependencies observed in a large study of more than 2.5K operations of 40 industrial APIs. However, the expressiveness of the language to model real-world dependencies is still open to question and we aim to address this issue.

  • RQ2 - Validation. Do the analysis operations implemented in IDLReasoner work as expected? The implementation of the analysis operations is an error-prone process. Defects in the mapping to CSP and/or the involved tools could lead to unexpected functionality. By answering this question, we aim to assess that the analysis operations work as expected and to gain confidence in the correctness of the developed tools.

6.1 Expressiveness

To assess the expressiveness of IDL (RQ1), we evaluated the expresiveness of the language on the specification of inter-parameter dependencies in real-world APIs. Specifically, we selected 30 operations from 22 real-world APIs including Amazon Product Advertising, Box, GitHub, Groupon, PayPal, Shopify, Vimeo, and YouTube. A third part of the operations (10 out of 30) were taken from the APIs reviewed in our initial study of dependencies in web APIs, and the rest were selected from APIs not previously studied. All selected APIs are ranked among the most popular APIs in ProgrammableWeb [37]. In total, we specified 149 different dependencies using IDL covering the seven types of dependencies identified in our study. As expected, we found no issues related to expressiveness and all dependencies were succinctly specified using the constructs of the language. This supports the suitability of IDL for the specification of dependencies among input parameters in practice. The IDL specifications are publicly available in the IDL repository [19], as well as a brief description of the operations modelled and links to their corresponding API documentation.

6.2 Validation

For the validation of the developed tools (RQ2) we resorted to standard testing techniques. More specifically, we used equivalence partitioning, boundary-value analysis and combinatorial testing [1] for the construction of a test suite. In this scenario, the input domain is comprised of IDL4OAS specifications, individual parameters and API requests. For the parameters, we used 3 partitions: valid, dead and false optional. For the requests, we used 2 partitions: valid and invalid. As for the IDL4OAS specifications, we followed a combinatorial approach to cover all possible combinations of two different types of the following elements (so-called 2-wise testing or pairwise testing [32]): number of parameters (5, 10), percentage of optional parameters (0, 50, 100), type of parameters (Booleans, integers, strings, enumerated integers, enumerated strings), number of IDL dependencies (5, 10), type of IDL dependencies (Requires, Or, OnlyOne, AllOrNone, ZeroOrOne, Arithmetic/Relational, Complex), and size of complex IDL dependencies (2, 5). The set of possible combinations was generated using the combinatorial testing tool PICT [36], developed by Microsoft. We created additional specifications for testing the operations allRequests and numberOfRequests, since they require all parameters to have a finite domain. In total, we designed and developed 178 test cases to test the functionality of both the editor and the analysis library. In the case of IDLReasoner, all test cases were automated using JUnit 5 [23].

As an example, Table II shows one of the cases for the operation isValidRequest. The test case takes two inputs: a request and an IDL4OAS specification (Listing 8). The operation is expected to return false since, according to the specification, requests including the parameter p1 should include the parameters p2 or p3, but not both at the same time.

Test case 1 - isValidRequest
Inputs
Expected output
Request: {p1=false, p2=‘thing’, p3=-10}            False
IDL4OAS: Listing 8
Table II: Sample test case for the operation isValidRequest.
1/oneDependency:˙ get:˙ parameters:˙ - name: p1 [...]
2      - name: p2 [...]
3      - name: p3 [...]
4      - name: p4 [...]
5      - name: p5 [...]
6    x-dependencies:˙ - IF p1 THEN OnlyOne(p2, p3);
Listing 8: IDL4OAS document used in several test cases.

The test suite proved very useful to reveal failures in the developed tools, especially in IDLReasoner. Among other issues, fully documented in GitHub [19, 20], we detected and fixed faults related to the parsing of IDL specifications, their translation to MiniZinc files and the behaviour of the analysis operations for boundary cases such as operations without parameters. Once each issue was fixed, the suite was run again to make sure that no new defects had been introduced as a result of the changes, proving itself as a very effective tool for regression testing. Although performance is out of the scope of our work, it is worth mentioning that the execution of the whole suite took between 60 and 70 seconds in a standard PC running an Intel i5 processor with 16GB of RAM and a solid-state drive (SSD). As expected, most of the operations are run in a few milliseconds except the operations calculating all the possible requests of a specification, which are computationally expensive.

All the test cases, including their test inputs and expected outputs, are publicly available, as well as their implementation in JUnit [20]. We trust that this data will be helpful not only for the sake of reproducibility, but also for future extensions of the tool suite or alternative implementations.

7 Threats to Validity

Next, we discuss the possible internal and external validity threats that may have influenced our work, and how these were mitigated.

7.1 Internal Validity

Threats to the internal validity relate to those factors that might introduce bias and affect the results of our investigation. One of the main threats in this regard is the subjective and manual review process conducted for identifying inter-parameter dependencies in the online documentation of the subject APIs. Some dependencies might have been misclassified or simply overlooked. To mitigate this threat, the documentation of each API was carefully checked several times, recording all the relevant information for its later analysis, and also to enable replicability [7]. The impact of possible mistakes was also minimised by the large number of APIs and operations reviewed (40 APIs and 2,557 operations), which makes us remain confident of the overall accuracy of the results.

Another possible threat is related to the existence of bugs in the implementation of the tools provided. To mitigate this threat, both the DSL and the analysis library have been thoroughly tested using standard testing techniques such as equivalence partitioning and combinatorial testing. During the development of the tool, several bugs were detected, either by manual inspection or by running the test suite (178 test cases). All bugs have been fixed and they are fully documented on GitHub [19, 20]. At the end of the development process, the test suite ran without any failures.

7.2 External Validity

This concerns the extent to which we can generalise from the results obtained in the experiments. Our study on the existence of inter-parameter dependencies in practice is based on a subset of 40 web APIs, and thus our results may not generalise to other APIs. To minimise this threat, we systematically selected a large set of real-world APIs from multiple application domains, including some of the most popular APIs in the world with millions of users worldwide.

As another threat, the DSL proposed in this paper could not be expressive enough to model all kinds of dependencies found in web APIs. However, several reasons make us confident in the expresiveness of the language. First, IDL is partially inspired by the grammar of PICT, a mature combinatorial testing tool developed by Microsoft. Second, IDL is based on the findings of a thorough study of over 600 dependencies found in more than 2.5K operations. Finally, and more importantly, we were able to model a total of 149 new dependencies from 22 real-world APIs, without identifying expresiveness issues.

Finally, our work lacks an empirical validation with software developers and practitioners that ensures the usefulness and usability of the developed tools. IDL might be considered hard to understand or to familiarise with. To minimise this threat, the language provides syntactic sugar to make dependencies self-explanatory (i.e., Or, OnlyOne, AllOrNone and ZeroOrOne). Also, we have proposed IDL4OAS, which allows to succinctly specify inter-parameter dependencies in OAS, the de-facto standard for API specification in industry.

8 Related Work

Two related papers have addressed the issue of inter-parameter dependencies in web APIs. Wu et al. [49] presented an approach for the automated inference of dependency constraints among input parameters in web services. As a part of their work, they studied four popular web APIs and classified the dependencies found into six types, four of which are specific instances of the Requires dependency presented in our work. Oostvogels et al. [33] proposed a DSL for the description of inter-parameter constraints in OAS. They first classified dependencies into three types: exclusive (called OnlyOne in our work), dependent (Requires in our work), and group constraints (AllOrNone in our paper). Then, they looked for instances of those types of dependencies in the documentation of six popular APIs by searching for specific keywords such as “either” or “one of”. Compared to theirs, our work is based on a much larger and systematic study: we have manually reviewed 40 APIs from different domains, whereas they have jointly studied 7 “popular” APIs. As a result, the conclusions drawn from our study differ from theirs. For example, we identified a richer set of dependencies (e.g., the DSL from Oostvogels et al. [33] does not support all dependency types from our catalogue) and observed a different trend regarding the frequency of dependencies in real-world web APIs (e.g., Wu et al. [49] found an average of 21.9% of API operations to have dependencies, while in our study that percentage is 9.7%). Furthermore, our work is the first to fully address both the specification and automated analysis of inter-parameter dependencies.

In the context of RESTful web APIs, RAML [39] seems to be the only specification language that provides some support for the description of inter-parameter dependencies, albeit minimal. Mutually exclusive parameters (i.e., OnlyOne dependencies from our catalogue) can be specified with the so-called union type, where a piece of data can be described by any of several types. For example, to describe an operation with one required parameter p1 and two mutually exclusive parameters p2 and p3, it could be done as follows: “queryString: type: [p1, p2 | p3]”. However, RAML does not offer support for the remaining six dependency types presented in this article, which represent 83% of the dependencies found in our study of real-world web APIs [26].

Other than RESTful services, several authors [51, 13, 5] have partially addressed the specification, inference or analysis of inter-parameter dependencies in other types of web services such as WSDL [48] and OWL-S [35], technologies increasingly in disuse nowadays. Compared to them, our approach is specification-independent and is based on the first large-scale study of inter-parameter dependencies in web APIs [26].

Regarding the specification of dependencies, combinatorial test case generation tools offer similar capabilities to specify constraints among input parameters, e.g., TestCover [46], Advanced Combinatorial Testing System (ACTS) [55] and Pairwise Independent Combinatorial Testing (PICT) [36]. Unfortunately, these tools were not designed with reusability in mind and their use out of the context of testing is hardly possible. The syntax of IDL is partially based on that of PICT, a fully-fledged tool developed by Microsoft. However, we extended the constraints grammar of PICT to support the seven types of dependencies from our catalogue [26], and to provide syntactic sugar that makes dependencies succinct and self-explanatory.

Regarding the automated analysis of IDL specifications, our proposal is inspired by previous work by the authors in the context of feature models, where more than 30 different analysis operations have been proposed [2]. Also, we were pioneers on the automated analysis of service level agreements in different web service technologies such as WS-Agreement [30, 29, 28], Linked USDL [14] and recently in OAS [12]. Both lines of research have served as the basis for the contributions presented in this paper where, although with similar ideas, we had to face unique challenges due to the richer catalogue of dependency patterns found in web APIs.

9 Conclusions

This article addressed the problem of specifying the dependencies among input parameters in web APIs. We presented a domain specific language, IDL, specifically designed to express the seven types of dependencies observed in a thorough study of more than 2.5K operations from 40 industrial APIs. Besides this, we proposed a catalogue of nine analysis operations to extract helpful information from IDL specifications such as detecting inconsistencies or checking the validity of API requests. For the automation of the analysis operations we proposed translating IDL specifications to CSPs and leveraging the capabilities of state-of-the-art CSP solvers. The approach is supported by an (Eclipse) editor, a parser, an OAS extension, and an analysis library validated through a thorough test suite of 178 test cases. Together, these contributions not only provide a complete solution to the automated management of inter-parameter dependencies in web APIs, but they also open a new range of applications and research opportunities in areas such as code generation, monitoring and testing.

There are a number of possible lines of future work. First, new analysis operations could be defined to further leverage IDL specifications. For example, the explanation feature integrated in most CSP solvers could be used to explain the causes of inconsistencies, e.g., why a given parameter is dead. Second, the integration of IDL in other API specification languages like RAML would facilitate its adoption and would further test the generalisability of our approach. Last, but not least, our contributions pave the way for new promising applications by leveraging both the specification of dependencies and their automated analyses.

Verifiability

For the sake of verifiability, we provide an online appendix pointing to the resources used in this article [43]: (1) links to the GitHub repositories of IDL and IDLReasoner, (2) dataset of our study on the presence of inter-parameter dependencies on real-world web APIs, (3) links to the documentation of the web APIs involved in the study and in the expressiveness assessment (RQ1), (4) test suite used for the validation of our approach (RQ2), and (5) demo video showing the capabilities of the IDL editor and the analysis library.

Acknowledgements

This work has been partially supported by the European Commission (FEDER) and Spanish Government under projects APOLO (US-1264651) and HORATIO (RTI2018-101204-B-C21), and the FPU scholarship program, granted by the Spanish Ministry of Education and Vocational Training (FPU17/04077). We would also like to thank Roberto Hermoso for his technical support during the development of IDLReasoner.

References

  • [1] P. Ammann and J. Offutt, Introduction to Software Testing.   Cambridge University Press, 2016.
  • [2] Benavides, D., Segura, S., Ruiz-Cortés, A., “Automated Analysis of Feature Models 20 Years Later: A Literature Review,” Information Systems, vol. 35, no. 6, pp. 615 – 636, 2010.
  • [3] “Bing Web Search API,” accessed January 2020. [Online]. Available: https://docs.microsoft.com/en-us/rest/api/cognitiveservices/bing-web-api-v7-reference
  • [4] “Bing Maps API,” accessed January 2020. [Online]. Available: https://msdn.microsoft.com/en-us/library/ff701702.aspx
  • [5] D. Cacciagrano, F. Corradini, R. Culmone, and L. Vito, “Dynamic Constraint-based Invocation of Web Services,” in 3rd Intern. Workshop on Web Services and Formal Methods, 2006, pp. 138–147.
  • [6] “The Chuffed CP solver,” accessed January 2020. [Online]. Available: https://github.com/chuffed/chuffed
  • [7] “Inter-Parameter Dependencies in RESTful APIs [Dataset],” 2019. [Online]. Available: https://bit.ly/2wvv1m1
  • [8] R. T. Fielding, “Architectural Styles and the Design of Network-based Software Architectures,” Ph.D. dissertation, 2000.
  • [9] “Flickr API,” accessed January 2020. [Online]. Available: https://www.flickr.com/services/api/
  • [10] “Forte API,” accessed January 2020. [Online]. Available: https://restdocs.forte.net/
  • [11] “Foursquare API,” accessed January 2020. [Online]. Available: https://developer.foursquare.com/places-api
  • [12] A. Gamez-Diaz, P. Fernandez, and A. Ruiz-Cortés, “Governify for APIs: SLA-Driven Ecosystem for API Governance,” in ACM Joint Meeting on European Software Engineering Conference and Symposium on the Foundations of Software Engineering, 2019, p. 1120–1123.
  • [13] C. Gao, J. Wei, H. Zhong, and T. Huang, “Inferring Data Contract for Web-based API,” in IEEE Intern. Conference on Web Services, 2014, pp. 65–72.
  • [14] J. García, P. Fernandez, C. Pedrinaci, M. Resinas, J. Cardoso, and A. Ruiz-Cortés, “Modeling Service Level Agreements with Linked USDL Agreement,” IEEE Transactions on Services Computing, vol. 10, no. 1, pp. 52–65, 2017.
  • [15] “GECODE - An open, free, efficient constraint solving toolkit,” accessed January 2020. [Online]. Available: https://www.gecode.org/
  • [16] “GeoNames API,” accessed January 2020. [Online]. Available: http://www.geonames.org
  • [17] “GitHub API,” accessed January 2020. [Online]. Available: https://developer.github.com/v3/
  • [18] “Google Maps API,” accessed January 2020. [Online]. Available: https://developers.google.com/places/web-service/intro
  • [19] “Inter-parameter Dependency Language (IDL),” accessed January 2020. [Online]. Available: https://github.com/isa-group/IDL
  • [20] “IDLReasoner: An Analysis Library for IDL Specifications,” accessed January 2020. [Online]. Available: https://github.com/isa-group/IDLReasoner
  • [21] D. Jacobson, G. Brail, and D. Woods, APIs: A Strategy Guide.   O’Reilly Media, Inc., 2011.
  • [22] D. Jacobson and S. Narayanan, “Netflix API: Top 10 Lessons Learned,” in Open Source Convention (OSCON), Porland, Oregon, July 2014. [Online]. Available: http://www.slideshare.net/danieljacobson/top-10-lessons-learned-from-the-netflix-api-oscon-2014
  • [23] “JUnit 5,” accessed January 2020. [Online]. Available: http://junit.org/junit5/
  • [24] “Last.fm API,” accessed January 2020. [Online]. Available: https://www.last.fm/api
  • [25] “Language Server Protocol,” accessed January 2020. [Online]. Available: https://microsoft.github.io/language-server-protocol
  • [26] A. Martin-Lopez, S. Segura, and A. Ruiz-Cortés, “A Catalogue of Inter-Parameter Dependencies in RESTful Web APIs,” in Intern. Conference on Service-Oriented Computing, 2019, pp. 399–414.
  • [27] “MiniZinc: Constraint Modeling Language,” accessed November 2019. [Online]. Available: https://www.minizinc.org/
  • [28] C. Müller, M. Oriol, X. Franch, J. Marco, M. Resinas, A. Ruiz-Cortés, and M. Rodríguez, “Comprehensive Explanation of SLA Violations at Runtime,” IEEE Transactions on Services Computing, vol. 7, no. 2, pp. 168–183, 2014.
  • [29] C. Müller, A. M. Gutierrez Fernandez, P. Fernandez, O. Martin-Diaz, M. Resinas, and A. Ruiz-Cortes, “Automated Validation of Compensable SLAs,” IEEE Transactions on Services Computing, 2018, article in press.
  • [30] C. Müller, M. Resinas, and A. Ruiz-Cortés, “Automated Analysis of Conflicts in WS–Agreement,” IEEE Transactions on Services Computing, vol. 7, no. 4, pp. 530–544, 2014.
  • [31] “NationBuilder API,” accessed January 2020. [Online]. Available: https://nationbuilder.com/api_documentation
  • [32] C. Nie and H. Leung, “A Survey of Combinatorial Testing,” ACM Computing Surveys, vol. 43, no. 2, 2011.
  • [33] Oostvogels, N., De Koster, J., De Meuter, W., “Inter-parameter Constraints in Contemporary Web APIs,” in 17th Intern. Conference on Web Engineering, 2017, pp. 323–335.
  • [34] “OpenAPI Specification,” accessed March 2019. [Online]. Available: https://github.com/OAI/OpenAPI-Specification
  • [35] “Semantic Markup for Web Services (OWL-S),” accessed November 2019. [Online]. Available: https://www.w3.org/Submission/OWL-S/
  • [36] “Microsoft PICT - Pairwise Independent Combinatorial Testing,” accessed October 2019. [Online]. Available: https://github.com/microsoft/pict
  • [37] “ProgrammableWeb API Directory,” accessed March 2019. [Online]. Available: http://www.programmableweb.com/
  • [38] “QuickBooks Payments API,” accessed January 2020. [Online]. Available: https://developer.intuit.com/app/developer/qbpayments/docs/get-started/
  • [39] “RESTful API Modeling Language (RAML),” accessed March 2019. [Online]. Available: http://raml.org/
  • [40] “RapidAPI API Directory,” accessed March 2019. [Online]. Available: https://rapidapi.com
  • [41] L. Richardson, M. Amundsen, and S. Ruby, RESTful Web APIs.   O’Reilly Media, Inc., 2013.
  • [42] “Stripe API,” accessed January 2020. [Online]. Available: https://stripe.com/docs/api
  • [43] “Supplementary material of the paper.” [Online]. Available: https://isa-group.github.io/2020-02-inter-parameter-dependencies
  • [44] “Swagger,” accessed March 2019. [Online]. Available: http://swagger.io/
  • [45] A. H. M. Ter Hofstede and H. A. Proper, “How to Formalize It? Formalization Principles for Information System Development Methods,” Information and Software Technology, vol. 40, pp. 519–540, 1998.
  • [46] “Testcover.com,” accessed January 2020. [Online]. Available: https://www.testcover.com/
  • [47] “Twilio API,” accessed January 2020. [Online]. Available: https://www.twilio.com/docs/usage/api/
  • [48] “Web Services Description Language (WSDL) Version 2.0,” accessed November 2019. [Online]. Available: https://www.w3.org/TR/wsdl20/
  • [49] Q. Wu, L. Wu, G. Liang, Q. Wang, T. Xie, and H. Mei, “Inferring Dependency Constraints on Parameters for Web Services,” in Proceedings of the 22nd Intern. Conference on World Wide Web, 2013, pp. 1421–1432.
  • [50] “Xtext,” accessed October 2019. [Online]. Available: https://www.eclipse.org/Xtext/index.html
  • [51] L. Xu, Q. Yuan, J. Wu, and C. Liu, “Ontology-based Web Service Robustness Test Generation,” in IEEE Intern. Symp. on Web Systems Evolution, 2009, pp. 59–68.
  • [52] “Yelp API,” accessed January 2020. [Online]. Available: https://www.yelp.com/developers/documentation/v3
  • [53] “Twitter API,” accessed January 2020. [Online]. Available: https://developer.twitter.com/en/docs
  • [54] “YouTube Data API v3,” accessed January 2019. [Online]. Available: https://developers.google.com/youtube/v3/
  • [55] L. Yu, Y. Lei, R. N. Kacker, and D. R. Kuhn, “ACTS: A Combinatorial Test Generation Tool,” in International Conference on Software Testing, Verification and Validation, 2013, pp. 370–375.