My notes on the book The Design of Web APIs. I highly recommend it as a great resource on designing high quality RESTful web APIs.
Fundamentals of API design
- An API is supposed to let your users easily achieve their goals, not the ones of the system exposing the API.
What is API design?
- APIs, whatever their types, simplify the creation of software, but remote APIs, and especially web ones, have revolutionized the way we create software.
- An API, whatever its type, is first and foremost an interface: a point where two systems, subjects, organizations, and so forth meet and interact.
- The mobile application is therefore called a consumer, and the backend is called a provider. These terms also apply respectively to the companies and the people creating the applications, or consuming or providing APIs.
- Web APIs unleash creativity and innovation by turning software into reusable bricks that can be easily assembled.
- In the API world, there are two types of bricks exposing two types of APIs: public APIs and private APIs.
- Public APIs are proposed as a service or as a product by others; you don’t build them, you don’t install them, you don’t run them—you only use them.
- A private API is one you build for yourself: only applications created by you or people inside your team, department, or company use it. In this case, you are your own API provider and API consumer.
- The public/private question is not a matter of how an API is exposed, but to whom. Even if it’s exposed on the internet, the mobile backend API is still a private one.
Why API design matters
- People expect these programming interfaces to be helpful and simple, just like any other (well-designed) interface.
- Developers expect APIs to be helpful and simple, just like any interface they have to interact with.
- An API is made to hide the implementation
- API design matters because when people use an API, they want to use it without being bothered by petty details that have absolutely nothing to do with them.
- The terrible consequences of poorly designed APIs
- A poorly designed product can be misused, underused, or not used at all. It can even be dangerous for its users and for the organization that created it, whose reputation is on the line.
- Flaws increase the time, effort, and money needed to build software using the API
- Design flaws increase the time, effort, and money needed to build software using the API. The API can be misused or underused. The users may need extensive support from the API provider, raising costs on the provider side.
- Flawed API design can also lead to security vulnerabilities in the API, such as exposing sensitive data inadvertently, neglecting access rights and group privileges, or placing too much trust in consumers.
The elements of API design
- Designing APIs without principles, totally out of context, and without taking into consideration both sides of the interface—the consumer’s side and also the provider’s—is the best way to ensure a total failure.
- The purpose of an API is to let people achieve their goals as simply as possible, whatever the programming part.
- Designing an API is about far more than just designing an easy-to-understand and easy-to-use interface on your own. We must design a totally secure interface—not unduly exposing sensitive data or actions to consumers. We must take the whole context into consideration—what the constraints are, how the API will be used and by whom, how the API is built, and how it could evolve. We have to participate in the whole API lifecycle, from early discussions to development, documentation, evolution, or retirement, and everything in between. And as organizations usually build many APIs, we should work together with all other API designers to ensure that all of the organization’s APIs have a similar look and feel in order to build individual APIs that are as consistent as possible, thus ensuring that the sum of all the APIs is as easy to understand and easy to use as each individual one.
- Web APIs turn software into reusable bricks that can be used over a network with the HTTP protocol.
- APIs are interfaces for developers who build the applications consuming them.
- API design matters for all APIs—public or private. Poorly designed APIs can be underused, misused, or not used at all, and even unsecure.
- Designing a good API requires that you take the whole context of the application into consideration, not only the interface
Designing an API for its users
- An API, like any everyday user interface, is made for its users in order to help them achieve their goals.
The right perspective for designing everyday user interfaces
- Focusing on how things work leads to complicated interfaces
- Creating an API that is an easy-to-use and easy-to-understand interface requires us to design it while being focused on the good point of view, the right perspective: what users can do.
- Viewing an API as software’s control panel
- This is how any API must be designed. An API must be designed from its consumer’s perspective and not its provider’s.
- An API designed from the provider’s perspective is only a window showing inner workings and, therefore, presenting goals that make sense only for the provider.
2.3 Identifying an API’s goals
- It is fundamental in designing an API to have a deep, accurate, and precise knowledge of:
- Who can use the API
- What they can do
- How they do it
- What they need to do it
- What they get in return
Identifying the whats and the hows
- What can users do? How do they do it?
- With these questions, we roughly describe what can be done with the API (the whats) and decompose them into steps (the hows), with each step becoming a goal of the API.
Identifying inputs and outputs
- What do they need to do it? What do they get in return?
- Identifying an API’s goals isn’t only about what can be done with it, but also what data can be manipulated through it.
Identifying missing goals
- Where do the inputs come from? How are the outputs used?
Identifying all users
- Identifying the different types of users is mandatory when building an exhaustive API goals list.
- Who are the users? What can they do? How do they do it? What do they need to do it? What do they get in return? Where do the inputs come from? How are the outputs used?
- If we first identify the different types of users of our API, we can build a comprehensive goals list more easily.
Using the API goals canvas
- The API goals canvas is nothing more than a table composed of six columns:
- Whos — Where you list the API’s users (or profiles)
- Whats — Where you list what these users can do
- Hows — Where you decompose each of the what’s into steps
- Inputs (source) — Where you list what is needed for each step and where it comes from (to spot missing whos, whats, or hows)
- Output (usage) — Where you list what is returned by each step and how it is used (to spot missing whos, whats, or hows)
- Goals — Where you explicitly and concisely reformulate each how + inputs + outputs
- The API goals canvas and its underlying questioning method help you envision who uses the API, what they can do with it, how they do it, what they need, and what they get in return.
- You should not dive too much into details at this stage.
Avoiding the provider’s perspective when designing APIs
- Whether you’re designing your API from scratch or basing it upon existing systems, the provider’s perspective will inevitably show up in every stage of its design.
“Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure.”
- Data, code and business logic, software architecture, and human organization shape the communication structure of a company and, therefore, can influence.
- Avoiding data influences
- It is unfortunately common to see API designs that mirror the underlying data organization.
- It would be better to replace these two fine-grained, data-oriented goals with a single, higher-level get customer’s information goal that is more consumer-oriented and both easy to understand and use.
- Using the API goals canvas and focusing on what users can do should allow you to easily avoid such design problems,
- Avoiding code and business logic influences
- The code that manipulates data—the implementation’s business logic—can influence API design.
- Avoiding software architecture influences
- It’s very common to build systems based on different pieces of software that communicate with each other (remember section 1.1.2 in chapter 1). Such a software architecture can influence API design in the same ways as internal business logic.
- Consumers don’t care about your software architecture choices. What they care about is seeing all the information they need about products when they search for them.
- Avoiding human organization influences
- As long as there is more than one person in an organization providing APIs, you will be confronted with
- Mapping API design to the underlying human organization can make the API hard to understand, hard to use, and even totally irrelevant.
- Detecting the provider’s perspective in the API goals canvas
- “Is all this really the consumer’s business?”
- With this question, as you have seen, we will check if any element comes from the provider’s perspective
Designing a programming interface
- Some of your goals cannot be represented easily. In such cases, you have to find a path between user-friendliness and compliance with the chosen API style in order to come up with the best possible representation.
Designing the API’s data
- Whatever the type of API, we start designing the data just like any programmable representation of a concept—just like a database table, a structure, or an object. We simply list the properties and stay consumer-oriented.
- Consumers must be able to understand the data, and we must not expose inner workings through its design. Once we’ve designed the core concepts, we can design the parameters and responses by adapting them. And finally, we must ensure that consumers will be able to provide all the data required to use the API.
- The most important information about a property is its name. The more self-explanatory the name is, the better.
- We also need to be clear about each property’s type.
- Consumers must be able to provide all of a parameter’s data, either because they know the information themselves or because they can retrieve it from the API.
- If data cannot be provided, it might be a sign of a missing goal or the provider’s perspective. Therefore, we must verify again that all the needed data can be provided by the consumer.
Striking a balance when facing design challenges
- REST trade-off examples
- Mapping actions on resources to HTTP methods and paths is not always straightforward.
- When a designer fails to map an action on a REST resource to any HTTP method, a first option is often to create an action resource
- An action resource is not a thing represented by a noun, but an action represented by a verb.
- An action resource can be seen as a method of a class and, therefore, can be represented as a sub-resource of a resource.
- An action resource absolutely does not conform to the REST model, but it works and is totally understandable by consumers.
- Sometimes you might not find the perfect API goal representation, even after intense brainstorming and with the help of the entire team. Sometimes you might not be really satisfied or even be a bit disappointed by an API design you are working on. Unfortunately, this is totally normal.
Understanding why REST matters for
- The aim of the REST architectural style is to facilitate building distributed systems that are efficient, scalable, and reliable.
- To be RESTful, software architecture needs to conform to the six following constraints:
- Client/server separation — There must be a clear separation of concerns when components like a mobile application and its API server work and communicate together.
- Statelessness — All information needed to execute a request is contained within the request itself. No client context is stored on the server in a session between requests.
- Cacheability — A response to a request must indicate if it can be stored (so a client can reuse it instead of making the same call again), and for how long.
- Layered system — When a client interacts with a server, it is only aware of the server and not of the infrastructure that hides behind it. The client only sees one layer of the system.
- Uniform interface — All interactions must be guided by the concept of identified resources that are manipulated through representations of resource states and standard methods. Interactions must also provide all metadata required to understand the representations and know what can be done with those resources. This is the most fundamental constraint of REST, and it is the origin of the Representational State Transfer name. Indeed, using a REST interface consists of transferring representations of a resource’s states.
Describing an API with an API description format
- An API description format is a simple and structured way to describe and share a programming interface.
- An API description document is a machine-readable document that can be used in numerous ways, including to generate API reference documentation.
- You use an API description format only when designing the API’s programmable representation and data, and not before.
- Always take advantage of an API description format’s documentation features. Explore the API description format’s documentation in depth so you can use it efficiently and, especially, to define reusable components where possible.
Designing a straightforward API
- People expect APIs to be usable. They expect straightforward representations, straightforward interactions, and straightforward flows.
- The choices you make with regard to names, data formats, and data can greatly enhance or undermine an API’s usability.
- Choose crystal-clear names
- Choose easy-to-use data types and formats
- Choosing ready-to-use data
- Any representation must be easily understandable by people and programs.
- Any representation must be as informative as possible.
- Error feedback must provide enough elements to understand and maybe fix the problem.
- Success feedback must describe what has been done.
- Goal flows can be optimized by adding data or goals to prevent errors.
- Goal flows can be simplified by aggregating goals, but only if that makes sense from a functional perspective.
Designing a predictable API
- To create APIs whose operations can be guessed, consistently define conventions and follow common practices and standards.
- Being consistent in your design not only makes your API easier to use, but also makes its design simpler.
- Always check if your API needs to provide different representation and/or localization and internationalization features.
- For each goal dealing with lists, consider whether paging, filtering, and sorting features will facilitate its use.
- In order to guide consumers, provide as much as metadata as possible (like hypermedia links, for example).
- Always check the underlying protocol and use its available features to make your API predictable, while taking care not to confuse users with complex or totally unused features.
Designing a concise and well-organized API
- “Less is more” and “a place for everything and everything in its place” are two adages that every API designer should apply.
- Organize data properties by sorting them, naming them using patterns, or grouping them in data structures.
- Categorize feedback and sort it by its importance.
- Group goals by focusing on functionality and not representations; you can use API description format features or naming patterns (OpenAPI tags and URL prefixes for REST APIs).
- Keep the number of properties and depth levels as low as possible in data structures.
- Avoid creating does-it-all goals. Split data structures, goals, and even APIs into smaller but functionally significant elements when possible.
Designing a secure API
- API security is not an afterthought that you can assume will be handled later (whenever that is) by the security people (whoever they are). Indeed, design and security are inextricably linked when creating an API or anything else.
- Security matters for all types of APIs; and, as an API designer, you have a part to play in API security.
- Access control and sensitive material are the primary areas where API security and API design intersect.
An overview of API security
- In order to design secure APIs, you must know some basic API security principles.
- When developers want to use an API in their consumer applications, whether they are mobile applications or backend ones, they must first register them. To do so, they can use the API provider’s developer portal.
- An ideal developer portal is a website offering documentation, tutorials, FAQs, forums, support, and any other useful resources and tools that developers can take advantage of to understand what the API does and how to use it.
Partitioning an API to facilitate access control
- We must group goals in scopes in order to grant consumers access to only selected goals.
“Every feature that is added to an application adds a certain amount of risk to the overall application. The aim for secure development is to reduce the overall risk by reducing the attack surface area.” OWASP
- By limiting consumers’ access to only the goals they really need, you reduce the likelihood of an attack. This is the principle of least privilege, which can also be applied to data.
- An API’s goals should be partitioned into various groups, called scopes, in order to enable access control mechanisms, and these scopes should be carefully designed.
- Scope strategies
- Defining flexible but complex fine-grained scopes: partitioning based on concepts and actions can produce scopes that are still flexible, but a little less fine-grained and complex.
- Defining simple but less flexible coarse-grained scopes
- Which strategy is the best when it comes to defining scopes to enable access control on an API? The flexible but complex fine-grained strategy or the less flexible but more user-friendly coarse-grained one? And within each strategy, which approach should you adopt? Unfortunately, there is no one right answer.
Designing with access control in mind
- Know what data is needed to control access
- Adapt the design when necessary
Handling sensitive material
- We must always check whether what can be requested, provided, or done through an API involves sensitive material. If so, we must ensure that it is really needed and then create the most secure design possible.
- As with designing secure data representations, you will have to talk to the security people in your organization in order to know which options are possible. Also, from a consumer experience perspective, if there’s a wide gap between the sensitive and non-sensitive versions of the data, it would be better to provide dedicated goals to access sensitive data instead of modulating the version returned, based on scopes or permissions.
- Designing secure error feedback
- You should also keep the risk of information leaks in mind when designing malformed request or functional error feedback.
- If you are designing a REST HTTP API, take care not to put any sensitive information in path parameters or query parameters because they can be logged.
Evolving an API design
- A breaking change is a change that will cause problems for consumers if they do not update their code. Most of the time you cannot synchronize an API update with all of its consumers’ updates, so trying to avoid such breaking changes or at least being aware of them when designing an API’s evolutions is definitely important.
Designing API evolutions
- Knowing how to avoid breaking changes when possible and handling them gracefully when not is, therefore, critical for an API designer.
- Avoid breaking changes in output data
- Avoid breaking changes to input data and parameters
- Avoid breaking changes to goals and flows
Versioning an API
- Choosing a versioning strategy affects not only how you design an API but also how you implement
- API and implementation versioning are different, and consumers (mostly) only care about the version changes announcing breaking changes.
- Choose an API versioning representation from the consumer’s perspective: the simplest options are path and domain versioning.
- Choose API versioning granularity: for REST APIs, besides at the API level, versioning can be done at the resource level, the goal/operation level, and the data/message level.
- Understand the impact of API versioning beyond design: even if the changes introduced in the API are not breaking ones, each of them must be carefully recorded so that you are able to communicate the list of changes to consumers.
Designing APIs with extensibility in mind
- By carefully designing data, interactions, and flows, and choosing the appropriate level of granularity for versioning, we can design extensible APIs that facilitate evolutions and, more importantly, lessen the risk of breaking changes.
Designing a network-efficient API
Overview of network communication concerns
- APIs can have different contexts than those we have just seen, but the network efficiency dimensions will usually resolve around these factors: speed, data volume, and number of calls. As API designers, we have to be aware of that and try to find a balance between the need for efficiency and an ideal design.
Ensuring network communication efficiency at the protocol level
- For HTTP-based APIs, activating compression and persistent connections can reduce data volume and latency. Enabling caching (letting consumers know if they can save a response to reuse it and for how long) and conditional requests (allowing consumers to check if the data they have is still fresh enough to avoid retrieving it again) can reduce not only the data volume but also the number of calls.
Ensuring network communication efficiency at the design level
- Providing filtering options is a good way to reduce the exchanged data volume because it allows consumers to get just what they really need.
- Providing filtering options is a good way to reduce the exchanged data volume because it allows consumers to get just what they really need.
- Which data you choose to return in lists can have a big impact on communication efficiency.
- Balance between the summarized representation of resources, usually returned in lists, and the detailed one, usually returned when accessing a specific resource.
- Fine-grained resources provide a flexible and precise way to get different subsets of data from a concept, but they can lead to many API calls when consumers need to get all the data.
By wisely using aggregation or using more complete representations in lists, we can design a more efficient API.
- By using content negotiation, we can design a much more flexible API providing, for example, three different representations of an owner. But that’s still a bit rigid. What if consumers only need to get summarized representations
- Resource expansion is another way of reducing the number of calls consumers might have to make to retrieve a data tree.
- We can make our API even more adaptable by letting consumers query the data they want, property by property, in order to reduce the data volume and, possibly, the number of API calls.
- Inefficient communication can be a symptom of a design that does not fulfill consumers’ actual needs.
- Providing relevant data also means not providing all the available data. Indeed, focusing on the consumer’s perspective can help to limit data volumes
- Adding more goals providing different access to the same resources or more direct access can also improve usability and efficiency in different contexts.
Designing an API in context
Adapting communication to the goals and nature of the data
- A synchronous request/response mechanism is not always the best option to represent a goal. Sometimes you might have to provide asynchronous goals.
- Consumer-to-provider communication is not always the most efficient way of communicating. Indeed, sometimes it can be useful to let the provider take the initiative.
- Reversing the consumer/provider communication can be done using a webhook, which is often described as a “reverse API.”
- Such a mechanism is not restricted to an asynchronous communication initiated by the consumer. It can also be used to notify consumers of events that are generated without any consumer interaction.
- Having a single webhook that receives lightweight, generic events is usually a good strategy. Such a webhook API is quite simple to implement and to consume, and adding new events is easy. You should always decide on what design to use according to your context.
- Streaming event flows: when an API provides data that always changes to consumers using a basic request/response goal, you can be sure that they will poll it continuously, making repeated API calls in order to get new or updated data.
- Using SSE, a server can send event data to consumers.
- Events and their data must make sense for consumers and must be easy to understand and use, to evolve, and to secure.
Observing the full context
- Designing APIs requires us to fully observe the context in which these will be consumed and provided in order to ensure that these fulfill all consumers’ needs in the best possible way—and actually be implementable by providers.
- Fulfilling all consumers’ needs means designing APIs that provide all the needed goals in an easy-to-understand and easy-to-use way; it also means being careful about some aspects that could be called nonfunctional requirements. These nonfunctional requirements basically concern how the API goals and data will actually be represented. Consumers can be used to certain practices or have some limitations that must be taken into account when designing APIs.
- We have to take into consideration what is happening behind the API in order to propose a design that will actually be not only usable, but also implementable.
Choosing an API style according to the context
- Choosing which tool(s) you will use to design a remote API must not be done based on what you are used to, what is fashionable, or your personal preference; it must be done according to the context.
- Whatever the provided framework, designers still have a lot of work to do in order to design decent APIs. Regardless of the API style they choose, designers still have to identify users, goals, inputs, outputs, and errors, and choose the best possible consumer-oriented representations while avoiding the provider’s perspective.
Documenting an API
- The best-known API documentation is the reference documentation that describes the interface contract of the API. It lists the available goals and describes their inputs and outputs. This is what you have to describe when designing an API, which can be sufficient for very basic APIs if all use cases fulfilled by the API can be accomplished using a single goal. But if that’s not the case, only supplying reference documentation is like only providing the list of ingredients for a recipe without some indication of what to do with those ingredients—an edible result might be quite hard to achieve from that. That is why an API must also come with an operating manual describing various use cases and how to achieve them.
Creating reference documentation
- Documentation can be generated from the implementation code alone or code plus annotations; that was the original intent of the Swagger framework. Such a strategy has the advantage of keeping implementation and documentation synchronized, but know that it has a few drawbacks:
- The resulting documentation will be far from complete.
- Including documentation in the code implies that you will actually modify the code to fix the documentation.
- In the early stages, code has to actually be written to generate documentation.
- Obviously, keeping the documentation outside the code can also have some drawbacks; the major one, being able to keep documentation and code synchronized. Know that there is no good or bad strategy regarding this matter; you have to choose one that works for you and your organization.
Creating a user guide
- Complete reference documentation listings and describing every component of an API is a must-have, but as mentioned earlier, when following a recipe, if you only have the ingredients list, you can struggle to achieve something edible. An API user guide, is meant to explain how to actually use the API. It describes how to use the API as a whole, as well as its principles and how to get access to it (registration and getting access tokens). When you’re providing public APIs, this documentation can be fairly dynamic.
- An API user guide can also contain information about all of the API’s common behaviors and principles; security is but one of these. Such documentation can explain how errors are handled, the available data formats and languages supported, or how pagination is handled.
- In sum, you should include everything that is common to your API goals and worth mentioning to consumers in order to facilitate the use of the API.
- Thinking beyond static documentation: the most-praised (public) APIs usually provide awesome developer portals, including high-quality reference documentation and user guides—and all of this is constructed in a totally dynamic way.
Providing adequate information to implementers
- The first step in providing relevant documentation to the API implementers is providing detailed consumer-facing documentation (a reference documentation and user guide). This documentation does not have to be flashy and eye-catching, but it must be exhaustive.
- The implementers also need provider-facing documentation about what actually happens under the hood. They need information about the data mapping (which system each piece of data comes from), error mapping (how to transform internal errors into consumer-facing errors), security data and controls, and expected behaviors based on internal business/technical rules.
Documenting evolutions and retirement
- Changes, breaking or not, will inevitably happen, and they have to be documented.
- Such documentation is useful for consumers to keep them aware of new features and let them know if they need to modify their code in the event that elements are deprecated (or worse, retired). It can be also useful for all the other people involved in the project, providing them with an overview of upcoming changes in the next version.
- A change log should state which elements (data model properties, parameters, responses, security scopes) have been added, modified, deprecated, or retired.
The API lifecycle
- API design is only a part of the API lifecycle: how APIs are born, live, and eventually retire.
- The API lifecycle starts with the analyze phase, where a company/organization/team/individual thinks providing an API might be of interest for business or technical reasons. During this phase, topics are explored, such as the API’s goals, what needs it is supposed to fulfill, what consumers it targets, who needs it, and what benefits it offers. Then comes the design phase, in which the ideas resulting from the Analyze phase are deeply investigated and transcribed into a programming interface contract. After that, during the implement phase, an application exposing this contract is built.
- After all this, the API is made available to the targeted consumers in the publish phase. The API will run this way until it evolves to provide new features. But it can also be retired because a new version introducing breaking changes is needed, with the previous version being replaced by the new one. Unfortunately, APIs can also be retired because they
- After all this, the API is made available to the targeted consumers in the publish phase. The API will run this way until it evolves to provide new features. But it can also be retired because a new version introducing breaking changes is needed, with the previous version being replaced by the new one. Unfortunately, APIs can also be retired because they were unsuccessful or are simply not needed anymore.
- To guarantee success, designers must work closely with stakeholders, product owners, technical writers, and developers or testers. They also have to work closely with consumers, either directly or through the API’s developer relations team.
Building API design guidelines
- Consistency is a key concern when designing APIs.
- Defining guidelines, a set of rules that will be used by all designers, is a must to ensure consistency within and across the organization/team’s APIs. It’s also a good way to avoid wasting time with endless debates where everyone is right, but a single solution has to be chosen, and to focus on what really matters: providing the easiest to understand and easiest to use representations of APIs that fulfill consumers’ needs.
- API design guidelines can be composed of three different layers: reference guidelines that focus on describing the foundations of the API designs (principles and rules), use case guidelines that explain how to apply these foundations through various uses cases, and design process guidelines that provide guidance about how to design APIs.
- Building API design guidelines requires us not only to actually write them, but also to evolve them and make people aware of them and accept them.
- Start by covering basic, necessary topics in a simple and straightforward way. Aim for completeness and accuracy.
- Rather than progressively adding everything that comes into your head in your API design guidelines, the idea is to only add field-proven content that has been used to solve an actual design question.
- Evolving API design guidelines obviously means dealing with breaking changes, versioning, and change logs.
- Building API design guidelines is not something that should be done alone by a single designer, or worse, by someone who has never put an API into production. The guidelines should be built collectively by actual designers for actual designers, without dogma, always willing to adjust/add/fix/evolve and even derogate when necessary.
- API design guidelines must not be enforced at all costs by the API police, and they should not reflect the ideas and preferences of a single individual.
Reviewing APIs What could go possibly wrong
- APIs have to be reviewed (validated, analyzed, scrutinized, checked, tested, and so on) at various stages of the API lifecycle to ensure that they work as intended. First and foremost, the needs have to be clearly identified and well understood, and it must be verified that creating an API is actually the best solution.
- As an API designer, it is your job to question, challenge, investigate, validate, and analyze everything regarding
- Asking questions, such as why something needs to be done, what the context is, and how it will be used, usually helps to identify the real need or needs hidden by the first demand.
Communicating and sharing
- To ensure consistency, your company’s guidelines (that you contribute to) should be easily accessible and known to all the API designers. All the existing APIs and data models should at least be easily findable (hence the source control system, wiki, or API catalog) and, if possible, searchable.