Commit a1e8c998 authored by Benni Mack's avatar Benni Mack

Merge branch '493-add-more-documentation-to-the-api' into 'develop'

[DOCS] Add more documentation to the API

Closes #493

See merge request t3o/ter!623
parents 8c4bb65c 6b6dd34f
Pipeline #10077 passed with stages
in 9 minutes and 2 seconds
......@@ -42,8 +42,12 @@ interface ApiUserInterface
/**
* Returns the keys of allowed extensions for the API user. This should
* be either all extensions the user is owner of, a defined subset or
* all extensions if the user has the controller (admin or review) scope.
* be either all extensions the user is owner of or a defined subset.
* This however only defines the extensions the user can modify. Using
* GET endpoints, user can also access (only read) other extensions.
*
* Note: If the user has the controller (admin or review) scope this
* will be empty, since the user is not checked for this property then.
*
* @return string[]
*/
......
......@@ -96,6 +96,22 @@ abstract class AbstractController implements RequestHandlerInterface
return $this->$action();
}
/**
* Validate all given route arguments using their isValid() function
* which calls all registered (based on the OpenAPI schema) validators.
*
* If a route argument is not valid, it's added to the $invalidArguments
* array. Since all route arguments implement jsonSerialize, we can simply
* add the array to the response and the specific implementation can deal
* with the output format.
*
* Note: It also supports so called "DataStructureRouteArguments" which
* contain sub arguments (properties).
*
* @param RouteArgumentStore $routeArgumentStore
*
* @return array
*/
protected function validateRouteArguments(RouteArgumentStore $routeArgumentStore): array
{
$invalidArguments = [];
......
......@@ -16,7 +16,11 @@ use Lcobucci\JWT\Signer;
use T3o\TerRest\Exception\SignatureKeysMissingException;
/**
* Signature implementation for ecdsa with Sha512 algorithm
* Signature implementation for ecdsa with Sha512 algorithm.
*
* Private and public key can either be defined via environment variables
* or as constructor arguments on instantiating. A passphrase is not required
* but highly recommended.
*/
final class EcdsaSignature implements SignatureInterface
{
......
......@@ -36,14 +36,14 @@ interface SignatureInterface
public function getAlgorithm(): string;
/**
* Return the signer and private key
* Return the signer and private key, used for signing
*
* @return array<Signer, Signer\Key>
*/
public function forSigning(): array;
/**
* Return the signer and public key
* Return the signer and public key, used for verification
*
* @return array<Signer, Signer\Key>
*/
......
......@@ -16,7 +16,10 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* Make authentication providers available in the container
* Make tagged authentication providers available in the container.
*
* Note: All authentication providers which implement
* AuthenticationProviderInterface are automatically tagged.
*/
final class AuthenticationProviderPass implements CompilerPassInterface
{
......
......@@ -17,7 +17,9 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
use T3o\TerRest\Authentication\Bearer\Grant\GrantFactory;
/**
* Make grant types available in the container
* Register tagged grant types and make them available in the container.
*
* Note: All grant types which implement GrantInterface are automatically tagged.
*/
final class GrantPass implements CompilerPassInterface
{
......
......@@ -17,7 +17,9 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
use T3o\TerRest\Crypto\SignatureFactory;
/**
* Make signatures available in the container
* Register tagged signatures and make them available in the container.
*
* Note: All signatures which implement SignatureInterface are automatically tagged.
*/
final class SignaturePass implements CompilerPassInterface
{
......
......@@ -18,7 +18,9 @@ use TYPO3\CMS\Core\Routing\RouteResultInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Create a request handler for the resolved route
* Create a request handler for the resolved route by searching
* in the container for the given service id. If not found, a new
* instance will be created.
*/
final class RequestHandlerFactory
{
......
......@@ -22,7 +22,14 @@ use TYPO3\CMS\Core\Http\JsonResponse;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Create a response object for the accepted type and the given data
* Create a response object for the accepted type and the given data.
*
* The API currently only supports JSON and falls back if another
* type is defined in the accept header. However, the functionality
* for implementing new response types is already given.
*
* There are several methods to create a response for different use
* cases like a created resource, a client error or a general error.
*/
final class ResponseFactory
{
......
......@@ -14,7 +14,6 @@ namespace T3o\TerRest\Repository;
/**
* Repository for authors
* Used for simple queries for which we don't need extbase data / relation mapping
*/
class AuthorRepository extends AbstractRepository
{
......
......@@ -16,7 +16,6 @@ use TYPO3\CMS\Core\Database\Query\QueryBuilder;
/**
* Repository for extensions
* Used for simple queries for which we don't need extbase data / relation mapping
*/
class ExtensionRepository extends AbstractRepository
{
......
......@@ -14,7 +14,6 @@ namespace T3o\TerRest\Repository;
/**
* Repository for frontend users
* Used for simple queries for which we don't need extbase data / relation mapping
*/
class FrontendUserRepository extends AbstractRepository
{
......
......@@ -14,7 +14,6 @@ namespace T3o\TerRest\Repository;
/**
* Repository for relations
* Used for simple queries for which we don't need extbase data / relation mapping
*/
class RelationRepository extends AbstractRepository
{
......
......@@ -14,7 +14,6 @@ namespace T3o\TerRest\Repository;
/**
* Repository for tags
* Used for simple queries for which we don't need extbase data / relation mapping
*/
class TagRepository extends AbstractRepository
{
......
......@@ -14,7 +14,6 @@ namespace T3o\TerRest\Repository;
/**
* Repository for versions
* Used for simple queries for which we don't need extbase data / relation mapping
*/
class VersionRepository extends AbstractRepository
{
......
......@@ -14,6 +14,11 @@ namespace T3o\TerRest\Routing;
/**
* Abstract class to be used by storage implementations
*
* Note: Extending classes must be immutable. The only
* way to add new properties is using the withProperty()
* method which creates a new storage based on the current
* properties plus the new one.
*/
abstract class AbstractStore implements \Countable
{
......@@ -33,7 +38,7 @@ abstract class AbstractStore implements \Countable
return isset($this->properties[$name]);
}
public function withArgument($property): self
public function withProperty($property): self
{
$clonedObject = clone $this;
$clonedObject->properties[$property->getName()] = $property;
......
......@@ -17,7 +17,26 @@ namespace T3o\TerRest\Routing\FormData;
*/
interface FormDataInterface
{
/**
* The form data field name as defined in the
* OpenAPI specification.
*
* @return string
*/
public function getName(): string;
/**
* The OpenAPI configuration of the field
*
* @return array
*/
public function getConfiguration(): array;
/**
* The value of the field. The data type depends on
* the specific implementation.
*
* @return mixed
*/
public function getValue();
}
......@@ -50,7 +50,7 @@ class ArrayArgument extends AbstractRouteArgument implements DataStructureRouteA
$itemConfiguration['schema'] = $configuration['schema']['items'] ?? [];
if ($itemConfiguration['schema'] !== []) {
$itemName = sprintf('%s[%s]', $name, $itemKey);
$this->properties = $this->properties->withArgument(
$this->properties = $this->properties->withProperty(
$routeArgumentFactory->create($itemName, $itemConfiguration, $itemValue)
);
}
......
......@@ -13,7 +13,7 @@ namespace T3o\TerRest\Routing\RouteArgument;
*/
/**
* Interface to be implemented by all arguments, containing sub properties (array or objects).
* Interface to be implemented by all arguments, containing sub properties (array or objects)
*/
interface DataStructureRouteArgumentInterface
{
......
......@@ -45,7 +45,7 @@ class ObjectArgument extends AbstractRouteArgument implements DataStructureRoute
foreach ($value as $property => $propertyValue) {
$propertyConfiguration['schema'] = $configuration['schema']['properties'][$property] ?? [];
if ($propertyConfiguration['schema'] !== []) {
$this->properties = $this->properties->withArgument(
$this->properties = $this->properties->withProperty(
$routeArgumentFactory->create($property, $propertyConfiguration, $propertyValue)
);
}
......
......@@ -17,15 +17,50 @@ namespace T3o\TerRest\Routing\RouteArgument;
*/
interface RouteArgumentInterface
{
/**
* The route argument name as defined in the
* OpenAPI specification.
*
* @return string
*/
public function getName(): string;
/**
* The OpenAPI configuration of the route argument
*
* @return array
*/
public function getConfiguration(): array;
/**
* The value of the route argument. The data type
* depends on the specific implementation.
*
* @return mixed
*/
public function getValue();
/**
* Check if a route argument is valid by calling
* all, based on the OpenAPI configuration,
* registered Validators.
*
* @return bool
*/
public function isValid(): bool;
/**
* Returns all validation errors of the route argument
*
* @return array
*/
public function getValidationErrors(): array;
/**
* To be used in responses. Should contain an appropriate
* representation of the value and possible validation errors.
*
* @return array
*/
public function jsonSerialize(): array;
}
......@@ -18,7 +18,11 @@ use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Provide the route configuration fetched from the schema specification
* Provides the route configuration fetched from the OpenAPI specification.
* Furthermore creates the route collection based on the specified endpoints
* and is also used during API runtime to retrieve information from the schema,
* to apply validation for arguments, reveal allowed authentication methods,
* required security options and so on.
*/
final class RouteConfiguration implements SingletonInterface
{
......
......@@ -24,9 +24,10 @@ use TYPO3\CMS\Core\Routing\RouteResultInterface;
* Resolve a route using the UrlMather and construct a RouteResultArguments
* object with the request handler reference (to further handle the request),
* the operationId (the specific action processing the request), authentication
* providers to be called beforehand and a RouteArgument collection for all
* arguments of the request including proper validation. Additionally all required
* arguments (based on the endpoint configuration) are checked for existence.
* providers to be called beforehand, a RouteArgument collection of all arguments,
* including proper validation and a FormData collection of all form data fields.
* Additionally all required - based on the endpoint configuration - arguments are
* being checked for existence.
*
* @see RouteResultArguments
*/
......
......@@ -13,9 +13,14 @@ namespace T3o\TerRest\Routing\Validaton;
*/
/**
* Enforce string representation of the validation error
* To be implemented by validation errors
*/
interface ValidationErrorInterface
{
/**
* Enforce string representation of the validation error
*
* @return string
*/
public function __toString(): string;
}
......@@ -18,7 +18,7 @@ use T3o\TerRest\DTO\ExtensionDemand;
use T3o\TerRest\Routing\RouteArgument\RouteArgumentStore;
/**
* Service for dealing with extension demand objects
* Service for dealing with the extension demand object
*/
class DemandService extends AbstractService
{
......
......@@ -100,7 +100,7 @@ class KeyService extends AbstractService
if ($formDataStore->hasProperty('tags')) {
$tagsCount = $this->addTags($formDataStore->getPropertyValue('tags'));
$formDataStore = $formDataStore->withArgument(new IntegerData('tags', [], $tagsCount));
$formDataStore = $formDataStore->withProperty(new IntegerData('tags', [], $tagsCount));
}
foreach ($formDataStore->getProperties() as $property) {
......
This diff is collapsed.
......@@ -18,7 +18,6 @@
"issues": "https://git-t3o.typo3.org/t3o/ter/issues"
},
"license": ["GPL-2.0-or-later"],
"version": "0.1.0",
"require": {
"php": "^7.4",
"typo3/cms-core": "^10.4"
......
......@@ -4,8 +4,8 @@ $EM_CONF[$_EXTKEY] = [
'title' => 'TYPO3 Extension Repository REST API',
'description' => 'REST API for the TYPO3 Extension Repository (TER).',
'category' => 'services',
'version' => '0.1.0',
'state' => 'alpha',
'version' => '0.2.0',
'state' => 'beta',
'author' => 'Oliver Bartsch',
'author_email' => 'oliver.bartsch@b13.com',
'author_company' => 'B13 GmbH',
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment