From 9933c48a4174c20f04fe328ec80f9d02654c8386 Mon Sep 17 00:00:00 2001
From: Sean Madsen <sean@seanmadsen.com>
Date: Tue, 25 Jul 2017 13:58:36 -0600
Subject: [PATCH] Import wiki page "API Architecture Standards"

from:
https://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards

Direct import (no modifications).
---
 docs/framework/api-architecture.md | 153 +++++++++++++++++++++++++++++
 mkdocs.yml                         |   1 +
 redirects/wiki-crmdoc.txt          |   1 +
 3 files changed, 155 insertions(+)
 create mode 100644 docs/framework/api-architecture.md

diff --git a/docs/framework/api-architecture.md b/docs/framework/api-architecture.md
new file mode 100644
index 00000000..7a2135a3
--- /dev/null
+++ b/docs/framework/api-architecture.md
@@ -0,0 +1,153 @@
+# API architecture
+
+
+The term 'API' refers to that code stored in the top level api folder.
+It's important to note that only compliant code & usage will be
+supported. Usage documentation is in the [API
+v3](/confluence/display/CRMDOC41/CiviCRM+Public+APIs) page.
+
+# API Architecture Standards
+
+-   The ONLY supported way to interact with any code in the API folder
+    from outside the api folder is by using the civicrm_api() wrapper
+-   Functionality delivered by the API is only supported if it is
+    1.  Advertised via the 'getfields function' OR (preferably AND)
+    2.  Verified by a test
+-   Where functions sit on the api but don't conform to the api
+    standards they may be supported by the creators but not by the
+    api team.
+
+## Individual API functions
+
+-   All functions MUST have a success test as a minimum (failure tests
+    are only required for special features). API functions without tests
+    are not supported & are, in fact, not considered to be part of
+    the API.
+-   There are a number of (fairly new) helper functions you should use
+    in the test - please check [Writing a PHPUnit testcase
+    HOWTO](/confluence/display/CRM/Writing+a+PHPUnit+testcase+HOWTO)
+-   API functions should match the relevant BAO names & have the
+    functions 'get', 'create' and delete'
+-   All functions should receive $params as an array(not a reference)
+-   All functions should return either\
+    -   an id indexed array of results via
+        the civicrm_api3_create_success() function
+    -   an appropriate message via throw new api_Exception
+-   (REVIEW this in light of feedback from bgm that it is not optimal
+    for translation) Do not use ts() in error messages (this will be
+    added in the exception function if you use api_Exception - but you
+    need to add a code)
+-   If a BAO object exists this must be passed to the create_success or
+    create_error function for freeing
+
+-   All setting of defaults, enforcement of required fields, management
+    of field aliases & field validation should be done at the wrapper
+    layer using the getfields function results
+-   Dates will be formatted to ISO format at the api layer, individual
+    functions should assume this (api layer uses strtotime())
+-   API functions should be accompanied by a _spec function to declare
+    fields & specifications for fields not retrieved from the
+    $dao-&gt;fields function or with different specifications to
+    those returned.
+-   All API functions should have a code comment block per standard
+    below
+-   As little functionality as possible should be in the API
+    functions themselves. Single line api functions should be the rule
+    not the exception. Where possible they should look like the
+    following basic functions:
+-   \
+
+        function civicrm_api3_survey_create($params) {
+          return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+        }
+
+
+
+        function civicrm_api3_survey_get($params) {
+          return _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+        }
+
+
+
+        function civicrm_api3_survey_delete($params) {
+          return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+        }
+
+## API code comment blocks
+
+-   API comment blocks shall include a description of the action & the
+    input and output params - per the example
+-   API comment blocks shall include a call to getfields per below -[the
+    output of which can be seen in the
+    phpdoc ](http://api.civicrm.org/v3/CiviCRM_APIv3/API_Survey/_api---v3---Survey.php.html#functioncivicrm_api3_survey_create){.external-link}
+-   API comment blocks shall include references to test generated
+    examples (these are generated by adding
+    $this-&gt;documentMe($params,$result,__FUNCTION__,__FILE__);
+    to tests
+
+<!-- -->
+
+    /**
+     * Create or update a survey
+     *
+     * @param array $params Associative array of property name/value
+     * pairs to insert in new 'survey'.
+     * @example SurveyCreate.php Std Create example
+     * @return array api result array
+     * {@getfields survey_create}
+     * @access public
+     */
+
+## getfields specifications
+
+The results of the getfields function is a combination of $dao-&gt;get
+and the _spec functions. Spec functions alter the generic getfields
+output (if any).
+
+-   The default wrapper will return unique functions for get functions &
+    table field names for create functions.
+-   Spec functions can define new fields by adding them to the $params
+    array (e.g below in function below)
+-   Required fields should be marked as 'api.required' (e.g below in
+    function below)
+-   Defaults should be marked as 'api.default' -e.g \
+    -   $params['is_active']['api.default'] = 1;
+
+-   Fields which should default to the value of another parameter should
+    be marked using 'api.aliases' - e.g\
+    -   $params['id']['api.aliases'] = array('field_id');// legacy support for field_id
+
+-   Where fields are marked with  'FKClassName' then the wrapper layer
+    will be able to return useful infomation if that constraint causes
+    the call to fail. (e.g below in function below)
+
+<!-- -->
+
+    /*
+     * Specify Meta data for create. Note that this data is retrievable
+     * via the getfields function and is used for pre-filling defaults
+     * and ensuring mandatory requirements are met.
+     *
+     * @param $params An array of parameters determined by getfields.
+     */
+    function _civicrm_api3_activity_create_spec(&$params) {
+     $params['subject']['api.required'] = 1;
+
+    $params['assignee_contact_id'] = array(
+     'name' => 'assignee_id',
+     'title' => 'assigned to',
+     'type' => 1,
+     'FKClassName' => 'CRM_Activity_DAO_ActivityAssignment',
+     );
+
+    $params['target_contact_id'] = array('name' => 'target_id',
+     'title' => 'Activity Target',
+     'type' => 1,
+     'FKClassName' => 'CRM_Activity_DAO_ActivityTarget',
+     );
+
+    $params['activity_status_id'] = array('name' => 'status_id',
+     'title' => 'Status Id',
+     'type' => 1,
+     );
+    }
diff --git a/mkdocs.yml b/mkdocs.yml
index fa21f22f..f2cf1a0a 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -60,6 +60,7 @@ pages:
     - "AngularJS: File Names": framework/angular/files.md
     - "AngularJS: Loader": framework/angular/loader.md
     - "AngularJS: Changesets":  framework/angular/changeset.md
+  - "API architecture": framework/api-architecture.md
   - Asset Builder: framework/asset-builder.md
   - Bootstrap Process: framework/bootstrap.md
   # Cache: /framework/cache.md
diff --git a/redirects/wiki-crmdoc.txt b/redirects/wiki-crmdoc.txt
index ba24220c..db0a14fb 100644
--- a/redirects/wiki-crmdoc.txt
+++ b/redirects/wiki-crmdoc.txt
@@ -134,3 +134,4 @@ Testing testing/setup
 PHP+Code+and+Inline+Documentation standards/php
 Upgrade+Reference framework/upgrade
 Bootstrap+Reference framework/bootstrap
+API+Architecture+Standards framework/api-architecture
-- 
GitLab