1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-30 09:20:58 +01:00

Continue hammering new *.search / *.edit documentation into shape

Summary: Ref T9964. Create some docuemntation for this stuff, and clean up the *.edit endpoints a bit.

Test Plan: Read documentation.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T9964

Differential Revision: https://secure.phabricator.com/D14798
This commit is contained in:
epriestley 2015-12-16 06:19:47 -08:00
parent 161ebad56d
commit 57cc30d0c4
9 changed files with 380 additions and 179 deletions

View file

@ -17,8 +17,8 @@ final class PhabricatorConduitApplication extends PhabricatorApplication {
public function getHelpDocumentationArticles(PhabricatorUser $viewer) { public function getHelpDocumentationArticles(PhabricatorUser $viewer) {
return array( return array(
array( array(
'name' => pht('Conduit Technical Documentation'), 'name' => pht('Conduit API Overview'),
'href' => PhabricatorEnv::getDoclink('Conduit Technical Documentation'), 'href' => PhabricatorEnv::getDoclink('Conduit API Overview'),
), ),
); );
} }

View file

@ -42,7 +42,9 @@ abstract class PhabricatorSearchEngineAPIMethod
final public function getMethodDescription() { final public function getMethodDescription() {
return pht( return pht(
'This is a standard **ApplicationSearch** method which will let you '. 'This is a standard **ApplicationSearch** method which will let you '.
'list, query, or search for objects.'); 'list, query, or search for objects. For documentation on these '.
'endpoints, see **[[ %s | Conduit API: Using Search Endpoints ]]**.',
PhabricatorEnv::getDoclink('Conduit API: Using Edit Endpoints'));
} }
final public function getMethodDocumentation() { final public function getMethodDocumentation() {

View file

@ -38,6 +38,15 @@ abstract class PhabricatorEditEngineAPIMethod
} }
final public function getMethodDescription() { final public function getMethodDescription() {
return pht(
'This is a standard **ApplicationEditor** method which allows you to '.
'create and modify objects by applying transactions. For documentation '.
'on these endpoints, see '.
'**[[ %s | Conduit API: Using Edit Endpoints ]]**.',
PhabricatorEnv::getDoclink('Conduit API: Using Edit Endpoints'));
}
final public function getMethodDocumentation() {
$viewer = $this->getViewer(); $viewer = $this->getViewer();
$engine = $this->newEditEngine() $engine = $this->newEditEngine()
@ -47,156 +56,106 @@ abstract class PhabricatorEditEngineAPIMethod
$out = array(); $out = array();
$out[] = pht(<<<EOTEXT $out[] = $this->buildEditTypesBoxes($engine, $types);
This is a standard **ApplicationEditor** method which allows you to create and
modify objects by applying transactions.
Each transaction applies one change to the object. For example, to create an
object with a specific title or change the title of an existing object you might
start by building a transaction like this:
```lang=json, name=Example Single Transaction
{
"type": "title",
"value": "New Object Title"
}
```
By passing a list of transactions in the `transactions` parameter, you can
apply a sequence of edits. For example, you'll often pass a value like this to
create an object with several field values or apply changes to multiple fields:
```lang=json, name=Example Transaction List
[
{
"type": "title",
"value": "New Object Title"
},
{
"type": "body",
"value": "New body text for the object."
},
{
"type": "projects.add",
"value": ["PHID-PROJ-1111", "PHID-PROJ-2222"]
}
]
```
Exactly which types of edits are available depends on the object you're editing.
Creating Objects
----------------
To create an object, pass a list of `transactions` but leave `objectIdentifier`
empty. This will create a new object with the initial field values you
specify.
Editing Objects
---------------
To edit an object, pass a list of `transactions` and specify an object to
apply them to with `objectIdentifier`. This will apply the changes to the
object.
You may pass an ID (like `123`), PHID (like `PHID-WXYZ-abcdef...`), or
monogram (like `T123`, for objects which have monograms).
Return Type
-----------
WARNING: The structure of the return value from these methods is likely to
change as ApplicationEditor evolves.
Return values look something like this for now:
```lang=json, name=Example Return Value
{
"object": {
"phid": "PHID-XXXX-1111"
},
"transactions": [
{
"phid": "PHID-YYYY-1111",
},
{
"phid": "PHID-YYYY-2222",
}
]
}
```
The `object` key contains information about the object which was created or
edited.
The `transactions` key contains information about the transactions which were
actually applied. For many reasons, the transactions which actually apply may
be greater or fewer in number than the transactions you provided, or may differ
in their nature in other ways.
Edit Types
==========
This API method supports these edit types:
EOTEXT
);
$key = pht('Key');
$description = pht('Description');
$head_type = pht('Type');
$table = array();
$table[] = "| {$key} | {$description} |";
$table[] = '|--------|----------------|';
foreach ($types as $type) {
$edit_type = $type->getEditType();
$edit_description = $type->getConduitDescription();
$table[] = "| `{$edit_type}` | {$edit_description} |";
}
$out[] = implode("\n", $table);
foreach ($types as $type) {
$section = array();
$section[] = pht('Edit Type: %s', $type->getEditType());
$section[] = '---------';
$section[] = null;
$section[] = $type->getConduitDescription();
$section[] = null;
$section[] = pht(
'This edit generates transactions of type `%s` internally.',
$type->getTransactionType());
$section[] = null;
$type_documentation = $type->getConduitDocumentation();
if ($type_documentation) {
$section[] = $type_documentation;
$section[] = null;
}
$type_description = pht(
'Use `%s` to select this edit type.',
$type->getEditType());
$value_type = $type->getConduitType();
$value_description = $type->getConduitTypeDescription();
$table = array();
$table[] = "| {$key} | {$head_type} | {$description} |";
$table[] = '|--------|--------------|----------------|';
$table[] = "| `type` | `const` | {$type_description} |";
$table[] = "| `value` | `{$value_type}` | {$value_description} |";
$section[] = implode("\n", $table);
$out[] = implode("\n", $section);
}
$out = implode("\n\n", $out);
return $out; return $out;
} }
private function buildEditTypesBoxes(
PhabricatorEditEngine $engine,
array $types) {
$boxes = array();
$summary_info = pht(
'This endpoint supports these types of transactions. See below for '.
'detailed information about each transaction type.');
$rows = array();
foreach ($types as $type) {
$rows[] = array(
$type->getEditType(),
$type->getConduitDescription(),
);
}
$summary_table = id(new AphrontTableView($rows))
->setHeaders(
array(
pht('Key'),
pht('Description'),
))
->setColumnClasses(
array(
'prewrap',
'wide',
));
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Transaction Types'))
->setCollapsed(true)
->appendChild($this->buildRemarkup($summary_info))
->appendChild($summary_table);
foreach ($types as $type) {
$section = array();
$section[] = $type->getConduitDescription();
$type_documentation = $type->getConduitDocumentation();
if (strlen($type_documentation)) {
$section[] = $type_documentation;
}
$section = implode("\n\n", $section);
$rows = array();
$rows[] = array(
'type',
'const',
$type->getEditType(),
);
$rows[] = array(
'value',
$type->getConduitType(),
$type->getConduitTypeDescription(),
);
$type_table = id(new AphrontTableView($rows))
->setHeaders(
array(
pht('Key'),
pht('Type'),
pht('Description'),
))
->setColumnClasses(
array(
'prewrap',
'prewrap',
'wide',
));
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Transaction Type: %s', $type->getEditType()))
->setCollapsed(true)
->appendChild($this->buildRemarkup($section))
->appendChild($type_table);
}
return $boxes;
}
private function buildRemarkup($remarkup) {
$viewer = $this->getViewer();
$view = new PHUIRemarkupView($viewer, $remarkup);
return id(new PHUIBoxView())
->appendChild($view)
->addPadding(PHUI::PADDING_LARGE);
}
} }

View file

@ -29,6 +29,9 @@
"userguide": { "userguide": {
"name": "Application User Guides" "name": "Application User Guides"
}, },
"conduit": {
"name": "API Documentation"
},
"fieldmanual": { "fieldmanual": {
"name": "Field Manuals" "name": "Field Manuals"
}, },

View file

@ -1,28 +0,0 @@
@title Conduit Technical Documentation
@group conduit
Technical overview of the Conduit API.
Overview
========
Conduit is the HTTP API for Phabricator. It is roughly JSON-RPC: you usually
pass a JSON blob, and usually get a JSON blob back, although both call and
result formats are flexible in some cases.
The easiest way to begin exploring Conduit is by visiting {nav Conduit} in the
web UI. The application provides an API console which you can use to explore
available methods, make calls, read documentation, and see examples.
The API console has details about how to construct calls and generate API
tokens for authentication.
The three primary ways to make Conduit calls are:
- `arc call-conduit`: You can use this `arc` command to execute low-level
Conduit calls.
- `curl`: You can format a call with basic HTTP parameters and cURL.
- `ConduitClient`:
There are also clients available in other languages. The Arcanist CLI client
for Phabricator is implemented over Conduit.

View file

@ -49,3 +49,11 @@ When the changelogs mention a method deprecation, you can use the call logs
to identify callers and notify them to upgrade or switch away. When the to identify callers and notify them to upgrade or switch away. When the
changelogs mention a method removal, you can use the call logs to verify that changelogs mention a method removal, you can use the call logs to verify that
you will not be impacted. you will not be impacted.
Next Steps
==========
Continue by:
- returning to @{article:Conduit API Overview}.

View file

@ -0,0 +1,68 @@
@title Conduit API Overview
@group conduit
Overview of the Conduit API.
Overview
========
Conduit is the HTTP API for Phabricator. It is roughly JSON-RPC: you usually
pass a JSON blob, and usually get a JSON blob back, although both call and
result formats are flexible in some cases.
API Clients
===========
The primary ways to make Conduit calls are:
**Web Console**: The {nav Conduit} application provides a web UI for exploring
the API and making calls. This is the best starting point for learning about
the API. See the next section for details.
`ConduitClient`: This is the official client available in `libphutil`, and
the one used by `arc`.
`arc call-conduit`: You can use this `arc` command to execute low-level
Conduit calls by piping JSON in to stdin. This can provide a simple way
to explore the API, or a quick way to get API access from a script written
in another language without needing a real client.
`curl`: You can format a call with basic HTTP parameters and cURL. The console
includes examples which show how to format calls.
**Other Clients**: There are also clients available in other languages. You
can check the [[ https://secure.phabricator.com/w/community_resources/ |
Community Resources ]] page for links.
API Console
===========
The easiest way to begin exploring Conduit is by visiting {nav Conduit} in the
web UI. The application provides an API console which you can use to explore
available methods, make calls, read documentation, and see examples.
The API console has details about how to construct calls and generate API
tokens for authentication.
Querying and Reading Objects
============================
For information on searching for objects and reading their properties and
information, see @{article:Conduit API: Using Search Endpoints}.
Creating and Editing Objects
============================
For information on creating, editing and updating objects, see
@{article:Conduit API: Using Search Endpoints}.
Next Steps
==========
Continue by:
- reading recommendations on responding to API changes in
@{article:Managing Conduit Changes}.

View file

@ -0,0 +1,115 @@
@title Conduit API: Using Edit Endpoints
@group conduit
Describes how to use edit endpoints to create and update objects.
Overview
========
Many applications provide `edit` endpoints, which are the primary way to
create and update objects (like tasks) using the API.
To create or edit an object, you'll build a list of //transactions// and pass
them to the endpoint. Each transaction applies a change to a field or property
on the object.
For example, a transaction might change the title of an object or add
subscribers.
When creating an object, transactions will be applied to an empty object. When
editing an object, transactions will be applied to an existing object.
The best reference for a particular `edit` endpoint is the Conduit API console.
For example, you can find the console page for `maniphest.edit` by navigating
to {nav Conduit > maniphest.edit} in the web UI. This page contains detailed
information about the endpoint and how it can be used.
Creating Objects
================
To create objects, pass a list of transactions but leave `objectIdentfier`
blank. This tells the endpoint that you want to create a new, empty object and
then apply the transactions to it.
Editing Objects
===============
To edit objects, pass a list of transactions and use `objectIdentifier` to
specify which object to apply them to. You can normally pass an ID or PHID,
and many applicaitons also allow you to pass a monogram (for example, you can
edit a task by passing `T123`).
Building Transactions
=====================
When creating or editing objects, you'll build a list of transactions to
apply. This transaction list will look something like this:
```lang=json, name="Example Transaction List"
[
{
"type": "title",
"value": "Assemble in the barnyard"
},
{
"type": "description",
"value": "All animals should assemble in the barnyard promptly."
},
{
"type": "subscribers.add",
"value": ["dog", "cat", "mouse"]
}
]
```
Applied to an empty object (say, a task), these transactions would create a new
task with the specified title, description and subscribers.
Applied to an existing object, they would retitle the task, change its
description, and add new subscribers.
The particular transactions available on each object are documented on the
Conduit API console page for that object.
Return Type
===========
WARNING: The structure of the return value from these methods is likely to
change as ApplicationEditor evolves.
Return values look something like this for now:
```lang=json, name=Example Return Value
{
"object": {
"phid": "PHID-XXXX-1111"
},
"transactions": [
{
"phid": "PHID-YYYY-1111",
},
{
"phid": "PHID-YYYY-2222",
}
]
}
```
The `object` key contains information about the object which was created or
edited.
The `transactions` key contains information about the transactions which were
actually applied. For many reasons, the transactions which actually apply may
be greater or fewer in number than the transactions you provided, or may differ
in their nature in other ways.
Next Steps
==========
Continue by:
- returning to the @{article:Conduit API Overview}.

View file

@ -0,0 +1,74 @@
@title Conduit API: Using Search Endpoints
@group conduit
Describes how to use search endpoints to find objects and read information.
Overview
========
Many applications provide `search` endpoints, which are the primary way to
get information about objects (like tasks) using the API.
To read information about objects, you'll specify a //query// which describes
which objects you want to retrieve. You can query for specific objects by
ID, or for a list of objects satisfying certain constraints (for example, open
tasks in a particular project).
The best reference for a particular `search` endpoint is the Conduit API
console. For example, you can find the console page for `maniphest.search` by
navigating to {nav Conduit > maniphest.search} in the web UI. This page
contains detailed information about the endpoint and how it can be used.
Specifying a Query
==================
The simplest query you can use is no query at all: just make a request with
no parameters. This will return the first page of visible objects. Most
applications sort objects by creation date by default, so usually this is
the 100 most recent objects.
The easiest way to constrain results is to use a builtin query or a custom
query that you build using the web UI. To do this, first issue the query in
the web UI (for example, by clicking the builtin link on the left nav of the
list view, or by submitting the query form).
The results page will include a //query key// in the URL. For builtin queries,
this is usually a human-readable term like `all` or `active`. For custom
queries, it is a hash value which looks something like `MT0Rh0fB2x4I`.
You can submit this key in the `queryKey` parameter to issue the exact same
query via the Conduit API. This provides a simple way to build complex queries:
just build the via the web UI, then reuse the same query in the API.
If you need more control or want to build dynamic queries, use the
`constraints` parameter to set constraints for individual query fields.
For more details, consult the Conduit API console documentation for the
method you're using. It includes documentation on all available constraints
and lists builtin and saved query keys.
Attachments
===========
By default, queries return basic information about objects. If you want more
detailed information, most applications offer //attachments// which can let
you retrieve more information.
For example, subscribers and projects are not returned by default, but you
can use subscribers to query them if you need this data.
Asking for more data means a slower query and a larger result, so usually you
should only ask for data you need.
The Conduit API console page for each query method has detailed information
on which attachments it supports.
Next Steps
==========
Continue by:
- returning to the @{article:Conduit API Overview}.