This is an automated email from the ASF dual-hosted git repository.

mitchell852 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new 4111e07  API Guidelines (#4716)
4111e07 is described below

commit 4111e076eec638fe21760eb3f3022225f514a4d2
Author: ocket8888 <[email protected]>
AuthorDate: Sat Jun 6 09:50:37 2020 -0600

    API Guidelines (#4716)
    
    * Added API Guidelines to official docs
    
    * Added toctree/links
    
    * Updated contribution guidelines
    
    * Fixed erroneous 'request' that should have been 'response'
    
    * Fixed incorrect header If-Not-Modified-Since to If-Unmodified-Since
---
 CONTRIBUTING.md                                    |   2 +-
 docs/source/development/api_guidelines.rst         | 268 +++++++++++++++++++++
 .../development/documentation_guidelines.rst       |   2 +
 docs/source/development/index.rst                  |   9 +-
 docs/source/development/traffic_ops.rst            |   2 +
 5 files changed, 278 insertions(+), 5 deletions(-)

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6963603..8497b8e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -57,7 +57,7 @@ If you've never made a pull request, it's super-easy. Github 
has a great tutoria
 
 Guidelines
 ----------
-Following the project conventions will make the pull request process go faster 
and smoother. If making changes to the Traffic Ops API, please consult the 
[Traffic Ops API 
Guidelines](https://cwiki.apache.org/confluence/display/TC/API+Guidelines).
+Following the project conventions will make the pull request process go faster 
and smoother. If making changes to the Traffic Ops API, please consult the 
[Traffic Ops API 
Guidelines](https://traffic-control-cdn.readthedocs.io/en/latest/development/api_guidelines.html).
 
 #### Create an issue or feature blueprint
 
diff --git a/docs/source/development/api_guidelines.rst 
b/docs/source/development/api_guidelines.rst
new file mode 100644
index 0000000..858a683
--- /dev/null
+++ b/docs/source/development/api_guidelines.rst
@@ -0,0 +1,268 @@
+..
+..
+.. Licensed under the Apache License, Version 2.0 (the "License");
+.. you may not use this file except in compliance with the License.
+.. You may obtain a copy of the License at
+..
+..     http://www.apache.org/licenses/LICENSE-2.0
+..
+.. Unless required by applicable law or agreed to in writing, software
+.. distributed under the License is distributed on an "AS IS" BASIS,
+.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+.. See the License for the specific language governing permissions and
+.. limitations under the License.
+..
+
+.. _api-guidelines:
+
+**************
+API Guidelines
+**************
+This section lays out guidelines to be considered by API endpoint authors. 
What follows are not *strictly* hard-and-fast rules, but there should be a very 
convincing argument accompanying endpoints that do not follow them.
+
+Legacy API versions don't, in general, adhere to these principles. This 
section is not meant as a proposal for altering them to be compliant, but 
merely a set of guidelines for future work.
+
+Response Bodies
+===============
+All valid API responses will be in the form of some serialized object. The 
main data that represents the result of the client's request MUST appear in the 
``response`` property of that object. If a warning, error message, success 
message, or informational message is to be issued by the server, then they MUST 
appear in the ``alerts`` property of the response. Some endpoints may return 
ancillary statistics such as the total number of objects when pagination 
occurs, which should be placed i [...]
+
+Response
+--------
+The ``response`` property of a serialized response object MUST only contain 
object representations as requested by the client. In particular, it MUST NOT 
contain admonitions, success messages, informative messages, or statistic 
summaries beyond the scope requested by the client.
+
+Equally unacceptable API responses are shown in :ref:`success-as-response` and 
:ref:`extra-field`.
+
+.. _success-as-response:
+.. code-block:: json
+       :caption: Success Message as Response Object
+
+       {
+               "response": "Thing was successfully created."
+       }
+
+.. _extra-field:
+.. code-block:: json
+       :caption: Illegal Top-Level Property
+
+       {
+               "response": {"foo": "bar"},
+               "someOtherField": {"someOtherObject"}
+       }
+
+When requests are serviced by Traffic Ops that pass data asking that the 
returned object list be filtered, the response property MUST be a filtered 
array of those objects (assuming the request may be successfully serviced). 
This is true even if filtering is being done according to a uniquely 
identifying property - e.g. a numeric ID. The ``response`` field of an object 
returned in response to a request to create, update, or delete one or more 
resources may be either a single object repres [...]
+
+The proper value of an empty collection is an empty collection. If a Foo can 
have zero or more Bars, then the representation of a Foo with no Bars MUST be 
an empty array/list/set, and in particular MUST NOT be either missing from the 
representation or represented as the "Null" value of the representation format. 
That is, if Foos have no other property than their Bars, then a Foo with no 
Bars may be represented in JSON encoding as ``{"bars":[]}``, but not as 
``{"bars":null}`` or ``{}``. S [...]
+
+As a special case, endpoints that report statistics including minimums, 
maximums and arithmetic means of data sets MUST use the property names ``min``, 
``max``, and ``mean``, respectively, to express those concepts. These SHOULD be 
properties of ``response`` directly whenever that makes sense.
+
+Alerts
+------
+Alerts should be presented as an array containing objects which each conform 
to the object definition laid out by :atc-godoc:`the ATC library's Alert 
structure <lib/go-tc#Alert>`. The allowable ``level``\ s of an Alert are:
+
+- ``error`` - This level MUST be used to indicate conditions that caused a 
request to fail. Because of this, this level MUST NOT appear in the ``alerts`` 
array of responses with any HTTP response code less than 400 (except when used 
for asynchronous tasks as discussed in `202 Accepted`_). Details of server 
workings and/or failing components MUST NOT be exposed in this message, which 
should otherwise be as descriptive as possible.
+- ``info`` - This level SHOULD be used to convey supplementary information to 
a user that is not directly the result of their request. This SHOULD NOT carry 
information indicating whether or not the request succeeded and why/why not, as 
that is best left to the ``error`` and ``success`` levels.
+- ``success`` - This level MUST be used to convey success messages to the 
client. In general, it is expected that the message will be directly displayed 
to the user by the client, and therefore can be used to add human-friendly 
details about a request beyond the response payload. This level MUST NOT appear 
in the ``alerts`` array of responses with an HTTP response code that is not 
between 200 and 399 (inclusive).
+- ``warning`` - This level is used to warn clients of potentially dangerous 
conditions when said conditions have not caused a request to fail. The best 
example of this is deprecation warnings, which should appear on all API routes 
that have been deprecated.
+
+Summary
+-------
+The ``summary`` object is used to provide summary statistics about object 
collections. In general the use of ``summary`` is left to be defined by API 
endpoints (subject to some restrictions). However, its use is not appropriate 
in cases where the user is specifically requesting summary statistics, but 
should rather be used to provide supporting information - pre-calculated - 
about a set of objects or data that the client *has* requested.
+
+Endpoints MUST use the following, reserved properties of ``summary`` for their 
described purposes (when use of ``summary`` is appropriate) rather than 
defining new ``summary`` or ``response`` properties to suit the same purpose:
+
+- ``count`` - Count contains an unsigned integer that defines the total number 
of results that could possibly be returned given the non-pagination query 
parameters supplied by the client.
+
+HTTP Request Methods
+====================
+:RFC:`7231#section-4` defines the semantics of HTTP/1.1 request methods. 
Authors should conform to that set of standards whenever possible, but for 
convenience the methods recognized by Traffic Ops and their meanings in that 
context are herein defined.
+
+GET
+---
+HTTP GET requests are issued by clients who want some data in response. In the 
context of Traffic Ops, this generally means a serialized representation of 
some object. GET requests MUST NOT alter the state of the server. An example of 
an API endpoint created in API version 1 that violates this restriction is 
:samp:`cdns/name/{name}/dnsseckeys/delete`.
+
+This is the standard method to be used by all read-only operations, and as 
such handlers for this method should generally be accessible to users with the 
"read-only" :term:`Role`.
+
+All endpoints dealing with the manipulation or fetching representations of 
"Traffic Control Objects" MUST support this method.
+
+POST
+----
+POST requests ask the server to process some provided data. Most commonly, in 
Traffic Ops, this means creating an object based on the serialization of said 
object contained in the request body, but it can also be used virtually 
whenever no other method is appropriate. When an object *is* created, the 
response body MUST contain a representation of the newly created object. POST 
requests do not need to be *idempotent*, unlike PUT requests.
+
+PUT
+---
+PUT is used to replace existing data with new data that is provided in the 
request body. :RFC:`2616#section-9.1.2` lists PUT as an "idempotent" request 
method, which means that subsequent identical requests should ensure the same 
state is maintained on the server. What this means is that a client that PUTs 
an object representation to Traffic Ops expects that if they then GET a 
representation of that object, do the same PUT again and GET another 
representation, the two retrieved represent [...]
+
+When an object is replaced, the response body MUST contain a representation of 
the object after replacement. While :RFC:`2616` states that servers MAY create 
objects for the passed representations if they do not already exist, 
:ref:`to-api` endpoint authors MUST instead use POST handlers for object 
creation.
+
+All endpoints that support the PUT request method MUST also support the 
:mailheader:`If-Unmodified-Since` HTTP header.
+
+PATCH
+-----
+At the time of this writing, no :ref:`to-api` endpoints handle the PATCH 
request method. PATCH requests that the server's stored data be mutated in some 
way using data provided in the request body. Unlike PUT, PATCH is not 
*idempotent*, which essentially means that it can be used to change only part 
of a stored object. When an object is modified, the response body MUST contain 
a representation of the object after modification, and that representation 
SHOULD fully describe the modified ob [...]
+
+Handlers that implement PATCH in the :ref:`to-api` MUST use conditional 
requests to ensure that race conditions are not a problem, specifically they 
MUST support using :mailheader:`ETag` and :mailheader:`If-Match`, and SHOULD 
also support :mailheader:`If-Unmodified-Since`.
+
+Clients SHOULD use PATCH requests rather than PUT requests for modifying 
existing resources whenever it is supported.
+
+DELETE
+------
+DELETE destroys an object stored on the server. Typically the request will 
contain identifying information for the object(s) to be destroyed either in the 
request URI or in the request's body. :ref:`to-api` endpoint authors MUST use 
this request method whenever an object identified by the request URI is being 
destroyed. When such deletion successfully occurs, the response body MUST 
contain a representation of the destroyed object.
+
+HTTP Response Codes
+===================
+Proper use of HTTP response codes can significantly improve user interfaces 
built on top of the API. What follows is a (non-exhaustive) set of response 
codes and their appropriate use in the context of Traffic Ops. For more 
complete information, refer to `the Mozilla Developer Network's HTTP Response 
Code list <https://developer.mozilla.org/en-US/docs/Web/HTTP/Status>`_.
+
+200 OK
+------
+This indicates the request succeeded, with no additional semantics. This MUST 
be the exact response status code of successful GET requests. This is also the 
default "success" response code for any other request.
+
+201 Created
+-----------
+This indicates that a resource was successfully created on the server. This 
MUST be the response status code of POST requests that create a new object or 
objects on the server, and in that case the response SHOULD also include a 
:mailheader:`Location` header that provides a URI where a representation of the 
newly created object may be requested.
+
+202 Accepted
+------------
+``202 Accepted`` MUST be used when the server is performing some task 
asynchronously (e.g. refreshing DNSSEC keys) but the status of that task cannot 
be ascertained at the current time. Ideally in this case, when the task 
completes - either successfully or by failing - the Traffic Ops changelog will 
be updated to indicate that status, along with information to uniquely identify 
the task (e.g. username and date/time when the task started).
+
+Endpoints that create asynchronous jobs SHOULD provide a URI to which the 
client may send GET requests to obtain a representation of the job's current 
state in the :mailheader:`Location` HTTP header. They MAY also provide an 
``info``-level Alert that provides the same or similar information in a more 
human-friendly manner.
+
+The responses to such GET requests are subject to the same restrictions as any 
other API endpoint, but have the added restriction that the ``response`` 
objects sent MUST have the ``status`` property, which is a string limited to 
one of the following values and having the associated semantics:
+
+PENDING
+       This means the job has been started but is not yet completed.
+SUCCEEDED
+       This means that the asynchronous job has completed and encountered no 
errors.
+FAILED
+       The task encountered errors and was unable to continue, and thus has 
been terminated.
+
+Note that the response code of the response carrying this information MUST NOT 
depend on the value of ``status``. In particular, a response that successfully 
reports the status of a FAILED asynchronous task is still successfully 
servicing a client's GET request, and therefore MUST have the ``200 OK`` 
response status code. However, a response encoding a FAILED ``status`` MUST be 
accompanied by one or more ``error``-level Alerts that explain (to the greatest 
degree of detail allowable secu [...]
+
+These responses MUST also include the ``startTime`` and ``endTime`` properties 
which indicate, respectively, the time at which the asynchronous job started 
and the time at which it concluded. A job that has not started MUST have a 
Null-valued ``startTime`` and likewise a job that has yet to conclude MUST have 
a Null-value ``endTime``.
+
+400 Bad Request
+---------------
+In general this is used when there's something syntactically wrong with the 
client's request. For example, Traffic Ops MUST respond with this code when the 
request body was improperly encoded. In most cases, this is also the proper 
response code when the client submits data that is not semantically correct. 
For example, dates/times represented as timestamp strings in an unsupported 
format should trigger this response code.
+
+This is also the default "client failure" response code for any other request.
+
+The response body MUST include an entry in the ``alerts`` array that describes 
to the client what was wrong with the request.
+
+401 Unauthorized
+----------------
+This MUST be the response code when a client without valid authorization 
information in the HTTP headers requests a resource which cannot be accessed 
without first authorizing. Which should be everything except ``/ping`` and 
endpoints that provide authorization.
+
+403 Forbidden
+-------------
+This MUST be used whenever the client is logged-in, but still does not have 
access to the resource they are requesting. It MUST also be used when they have 
some access to the resource, but not with the specific request method they 
used. This can pertain to restricted access on the basis of :term:`Role`, User 
Permissions, as well as :term:`Tenancy`.
+
+The response body MUST NOT disclose any information regarding why the user was 
denied access.
+
+404 Not Found
+-------------
+This MUST be the returned status code when the client requests a path that 
does not exist on the server. Note that a *path* does not include a *query 
string*; in the URL ``http://example.test/some/path?query#frag`` the *path* 
consists of only ``/some/path``.
+
+409 Conflict
+------------
+This SHOULD be used when the request cannot be completed because the current 
state of the server is fundamentally incompatible with the request. For 
example, creating a new user with an email that is already in use should result 
in this response.
+
+Additionally, this MAY be used instead of `404 Not Found`_ when the client is 
requesting a link between an object identified by the request URI and some 
other object (e.g. when assigning a :term:`cache server` to a :term:`Delivery 
Service`) when the other object does not exist. If the request URI identifies 
an object that does not exist, the response MUST use `404 Not Found`_ instead.
+
+This is also the proper response status code when the conditions of a request 
cannot be met, e.g. when a client submits a PATCH request for a resource with 
an :mailheader:`If-Match` header that does not match the stored object's 
:mailheader:`ETag`.
+
+The response body MUST indicate what the conflict is that prevented the 
request from being fulfilled via one or more ``error``-level alerts.
+
+500 Internal Server Error
+-------------------------
+When the Traffic Ops server encounters some error - through no fault of the 
client or their request - that renders it incapable of servicing the client's 
request, it MUST return this status code if no other code is more appropriate. 
The response body in this case SHOULD indicate that an error occurred, but MUST 
NOT divulge details about what data was being processed, what (if any) other 
components are not functioning properly, or what process failed. Generally it 
is advisable that the re [...]
+
+501 Not Implemented
+-------------------
+This is the response code used when the client requests an API version not 
implemented by the server. It SHOULD NOT be used in any other case.
+
+502 Bad Gateway
+---------------
+This code indicates that some other service on which the endpoint's processes 
depend has given back improper data or an error response. It MAY be used (with 
caution) by plugin developers, but SHOULD NOT be used by authors of proper API 
endpoints, as that divulges information about failing connected systems and 
potentially gives an attacker information about Traffic Control's weak points. 
API endpoint authors should instead use `500 Internal Server Error`_.
+
+504 Gateway Timeout
+-------------------
+This code indicates that a connection timeout occurred when attempting to 
contact some other service on which the endpoint's processes depend. It MAY be 
used (with caution) by plugin developers, but SHOULD NOT be used by authors of 
proper API endpoints, as that divulges information about failing connected 
systems and potentially gives an attacker information about Traffic Control's 
weak points. API endpoint authors should instead use `500 Internal Server 
Error`_.
+
+Documentation
+=============
+All endpoints MUST be properly documented. For guidelines for writing API 
documentation, refer to :ref:`api-doc-guidelines`.
+
+Passing Request Data
+====================
+Request data may be passed in the request body or as a 
:mimetype:`application/x-www-form-urlencoded`-encoded query string in the 
request URI, or as a part of the request path. Request data MUST NOT be passed 
through a portion of the request path unless it uniquely identifies a resource 
with which the client may interact. For example, :samp:`/foos/{ID}` is an 
acceptable path for dealing with the particular "Foo" object that has some 
identifier ``ID``, but :samp:`logs/{Number of Days}/days [...]
+
+When accepting data in the request body of requests, the endpoint MUST 
properly document the object representations (properties and their types) it 
accepts and MUST reject semantically invalid data with a `400 Bad Request`_ 
response code. For example, if an endpoint specifies it accepts a 
representation of a Foo object, assuming Foo objects possess only the Bar 
property which is an arbitrary string, then the endpoint MUST accept ``{"bar": 
"testquest"}`` as semantically valid (The data ma [...]
+
+The decision to pass data in the request body or query string is mainly up to 
the author, but some helpful tips:
+
+- GET and DELETE requests do not typically provide request bodies.
+- Query parameters should nearly always be optional. If data is required by an 
endpoint, consider requiring it in the request body. If the data identifies a 
resource, it ought to be a path parameter.
+- Request body data often represents objects that are being created or 
updated. If an object is being created or updated, it ought to be defined in 
the request body, and if any additional data is (possibly optionally) required 
then it ought to be passed in the query string to separate it from the object 
definition.
+- The following query parameters are reserved for special use by Traffic Ops 
endpoint handlers, and may not be used for any purpose other than their 
prescribed functions.
+
+       - ``limit``
+       - ``newerThan``
+       - ``offset``
+       - ``olderThan``
+       - ``orderby``
+       - ``page``
+       - ``sortOrder``
+
+Duplicate Endpoints
+===================
+No two endpoints should serve the same purpose. While it's fine to overlap a 
bit, an endpoint like ``/foo_bars`` should not exist solely to edit the Bars 
property of Foo objects (which can ostensibly be edited just fine on the object 
itself), for example. Ideally, there should be exactly one way to accomplish 
something through the API.
+
+A caveat, though, is object relationships. For example, a :term:`Delivery 
Service` has zero or more :term:`cache servers` assigned to it, and in turn 
:term:`cache servers` may be assigned to zero or more :term:`Delivery Services` 
(a "has-and-belongs-to-many" relationship). Thus it is permissible to be able 
to edit the :term:`Delivery Services` property of a :term:`cache server` using 
the ``/cache_servers`` API endpoint as well as to be able to edit the 
:term:`cache servers` property of a [...]
+
+Date/Time Format
+================
+Dates MUST be represented in either :RFC:`3339` (with or without nanosecond 
precision) or as integers indicating the number of nanoseconds past the Unix 
epoch at which the date/time occurs. In either case, Dates included in 
responses from Traffic Ops MUST be in UTC. Wherever date/times are accepted as 
input, :ref:`to-api` endpoints MUST accept either format and SHOULD NOT accept 
anything else.
+
+Traffic Ops endpoints MUST return dates and times in :RFC:`3339` format with 
nanosecond precision. Endpoints MAY provide ways for the client to specify 
alternate representations, but these SHOULD be restricted to only Unix epoch 
timestamps in nanoseconds.
+
+Age Filtering
+=============
+Whenever object age is a property of that object (which is quite often in the 
form of ``lastUpdated``), Traffic Ops endpoint handlers that respond to 
requests for object representations (i.e. GET requests) SHOULD support 
filtering by age. If age filtering is implemented, it MUST be made available 
using the query parameters in the table below.
+
+.. _age-filtering-qparams:
+.. table:: Age Filtering Query Parameters
+
+       
+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+       | Parameter     | Meaning                                               
                                                                                
                                   |
+       
+===============+==========================================================================================================================================================================+
+       | ``newerThan`` | A timestamp to be used as the lower limit on an 
object's age. Objects older than this MUST NOT appear in the response body. 
That is, the response will be the set of all |
+       |               | objects in the collection with a modification date 
that is greater than *or equal to* this value.                                  
                                      |
+       
+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+       | ``olderThan`` | A timestamp to be used as the upper limit an object's 
age. Objects newer than this MUST NOT appear in the response body. That is, the 
response will be the set of all    |
+       |               | objects in the collection with a modification date 
that is less than *or equal to* this value.                                     
                                      |
+       
+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+The format of these timestamps - in accordance with the `Date/Time Format`_ 
section - MUST be accepted as Unix epoch timestamps in nanoseconds, **and** in 
the form of :RFC:`3339` date/time strings.
+
+Endpoints MAY return errors when a client request gives these parameters 
improper or invalid values, but MUST at least provide a warning. When ambiguity 
or errors in age filtering controls render age filtering impossible, the 
handler MUST NOT perform age filtering.
+
+Tenancy
+=======
+When a client requests access to a set of stored objects that are "tenantable" 
inevitably some of them will be inaccessible to the user on the basis of their 
:term:`Tenant`. Traffic Ops endpoint handlers that respond to requests for such 
object representations (i.e. GET requests) MUST filter their results implicitly 
according to the requesting Tenant's access. Any request that would modify, 
create, or destroy an object to which the requesting :term:`Tenant` does not 
have access MUST NOT  [...]
+
+Naming Conventions
+==================
+The names of properties of objects as they appear in said objects' 
serializations ought to conform to "camelCase" naming. Initialisms, 
abbreviations, and acronyms that appear in property names should be capitalized 
unless they are at the very beginning of the name. For example, ``myIPAddress`` 
and ``someProperty`` are both well-formed property names, while ``IPAddress``, 
``someproperty`` and ``SomeProperty`` are not.
+
+Query string parameters MUST also follow "camelCase" naming.
+
+API endpoints themselves should have a name that conveys their purpose. For 
example, ``/cdns`` is an endpoint that deals with manipulating, creating, 
destroying, or retrieving representations of CDNs. Request paths MUST use 
"snake_case" to separate words whenever necessary, and MUST never include the 
action being performed by the handler; instead that is decided by the request 
*method*. For example, ``/myObject/delete`` is a poor request path name for 
both of those reasons. Furthermore,  [...]
+
+API endpoints MAY support trailing slashes (:kbd:`/`) in the request path, but 
MUST NOT include suffixes that indicate a particular encoding ("file 
extensions"); that's what the :mailheader:`Content-Type` header is for. For 
example, in API version 1.x, ``/foos`` and ``/foos.json`` are both equally 
valid ways to access the ``/foos`` endpoint handlers - this is no longer 
allowed!
+
+Relationships as Objects
+========================
+Relationships SHOULD NOT be represented through the API as objects in their 
own right. For example, instead of an endpoint like 
``/delivery_service_servers`` used to manipulate assignments of :term:`cache 
servers` to :term:`Delivery Services`, a :term:`Delivery Service` itself should 
have Servers as a property. Thus assignments are manipulated by manipulating 
that property. So the only endpoints necessary for fully defining and dealing 
with such relationships are ``/delivery_services`` a [...]
+
+Change Logging
+==============
+All manipulations of objects (i.e. any operation that is not merely "reading" 
data) MUST add a Change Log entry indicating what was changed.
diff --git a/docs/source/development/documentation_guidelines.rst 
b/docs/source/development/documentation_guidelines.rst
index 5428829..e7319ac 100644
--- a/docs/source/development/documentation_guidelines.rst
+++ b/docs/source/development/documentation_guidelines.rst
@@ -185,6 +185,8 @@ Terms
 Please always spell out the entire name of any Traffic Control terms used in 
the definition. For example, a collection of :term:`cache servers` associated 
with a certain physical location is called a "Cache Group", not a "CG", 
"cachegroup", "cache location" etc. A subdomain and collection of :term:`cache 
servers` responsible collectively for routing traffic to a specific origin is 
called a :term:`Delivery Service`", not a "DS", "deliveryservice" etc. 
Similarly, always use *full* permissi [...]
 Generally speaking, be wary of using the word "cache". To most people that 
means the *actual* cache on a hard disk somewhere. This word is frequently 
confused with " :term:`cache server`", which - when accurate - is always 
preferred over "cache".
 
+.. _api-doc-guidelines:
+
 Documenting API Routes
 ----------------------
 Follow all of the formatting conventions in `Formatting`_. Maintain the 
structural format of the API documentation as outlined in the :ref:`to-api` 
section. API routes that have variable paths e.g. :ref:`to-api-profiles-id` 
should use `mustache templates <https://mustache.github.io/mustache.5.html>`_ 
**not** the Mojolicious-specific ``:param`` syntax. This keeps the templates 
generic, familiar, and reflects the inability of a request path to contain 
procedural instructions or program log [...]
diff --git a/docs/source/development/index.rst 
b/docs/source/development/index.rst
index bc83f4c..862e1b3 100644
--- a/docs/source/development/index.rst
+++ b/docs/source/development/index.rst
@@ -21,12 +21,13 @@ Use this guide to start developing applications that 
consume the Traffic Control
 .. toctree::
        :maxdepth: 2
 
+       api_guidelines
        building
-       traffic_ops
+       debugging
+       documentation_guidelines
        ort/traffic_ops_ort
+       traffic_monitor
+       traffic_ops
        traffic_portal
        traffic_router
-       traffic_monitor
        traffic_stats
-       debugging
-       documentation_guidelines
diff --git a/docs/source/development/traffic_ops.rst 
b/docs/source/development/traffic_ops.rst
index 5bfa0cb..95d6744 100644
--- a/docs/source/development/traffic_ops.rst
+++ b/docs/source/development/traffic_ops.rst
@@ -521,6 +521,8 @@ Writing New Endpoints
 =====================
 All new :ref:`to-api` endpoints should be written in Go, so writing endpoints 
for the Perl implementation is not discussed here. Furthermore, most new 
endpoints are accompanied by database schema changes which necessitate a new 
migration under :atc-file:`traffic_ops/app/db/migrations` and database 
best-practices are not discussed in this section.
 
+.. seealso:: This section contains a quick overview of API endpoint 
development; for the full guidelines for API endpoints, consult 
:ref:`api-guidelines`.
+
 The first thing to consider when writing a new endpoint is what the requests 
it will serve will look like. It's recommended that new endpoints avoid using 
"path parameters" when possible, and instead try to utilize request bodies 
and/or query string parameters. For example, instead of ``/foos/{{ID}}`` 
consider simply ``/foos`` with a supported ``id`` query parameter. The request 
*methods* should be restricted to the following, and respect each method's 
associated meaning.
 
 DELETE

Reply via email to