SwiftAPI Documentation

website·Indexed 29 days ago

https://swiftapi.github.io/swift-docs/docs/

Documentation for the SwiftAPI framework, featuring guides on routing and controllers, GraphQL integration with Relay support, security components including authentication and rate limiting, database relations, and an asynchronous PHP runtime.

Tokens
27.4K
Snippets
121
Records
169
Agent score
75%

What's inside SwiftAPI

  1. Overview of Swift Logging

    The Swift logging component is a wrapper around the Monolog library, designed to integrate logging seamlessly into the framework. It provides a set of ready-to-go loggers and utilities, though developers can still use Monolog directly if preferred.
  2. Understand the difference between Users and Clients in Swift

    Swift distinguishes between two types of authenticated entities. Both are represented as implementations of Swift\Security\User\UserInterface after authentication for consistent usage across the application.

    • Users: End users of the application (e.g., customers).
    • Clients: API Consumers, represented by the Swift\Security\User\ClientUser class.
  3. Understand the Swift Database Abstraction Architecture

    The Swift database system uses a two-layer architecture to manage data:

    1. Database Abstraction Layer (DBAL): Powered by Cycle, this layer handles the driver-level communication with the database.
    2. Entity Layer: Uses PHP classes to represent Data Objects within the database.

    Swift employs a code-first approach where the database schema is defined within Entity classes. The ORM automatically synchronizes these definitions with the database schema and manages relationships between data objects, significantly reducing the need to write manual SQL statements.

  4. Swift PHP Framework Overview and Use Cases

    Swift is a lightweight PHP framework optimized for building APIs and microservices quickly. It is not intended for building full websites or large-scale monolithic applications. Instead, it is designed for specialized services such as:

    • Simple webservices and API proxies (bundling multiple endpoints or leveraging legacy APIs)
    • Data caching layers
    • REST or GraphQl API endpoints for headless front-ends
    • Real-time communication via Socket API endpoints or Server Sent Events (SSE)
    • Logging services and CDNs

    Under the hood, Swift leverages components from Symfony, Cycle ORM, and graphql-php.

  5. Use PHP 8 attributes for metadata and configuration

    The system utilizes PHP 8 attributes to attach metadata and configuration directly to classes, properties, methods, and method arguments. This approach replaces Doctrine Annotations and eliminates the need for separate configuration files (e.g., for defining routes), keeping the logic and its configuration co-located for better maintainability and visibility.
  6. Understand Swift GraphQL implementation and schema generation

    Swift provides a GraphQL component as an alternative to REST endpoints, implementing a declarative, code-first approach inspired by Nexus. It is a wrapper for Webonyx GraphQL and complies with the GraphQL Spec and the Relay Specification.

    By default, Swift automatically generates the following for all entities:

    • Queries: A query to fetch a single entity by ID and a query to fetch a list (Connection) of entities.
    • Mutations: Mutations to create, update, and delete entities.
  7. Understand the Swift Application architecture and request flow

    The Swift application architecture is designed to be small and composable, relying heavily on middleware for its core logic. The request flow follows a specific sequence: the Application bootstraps the Kernel, which then executes a stack of Middleware to process the request and generate a response.
  8. Create a new entity record

    To create a new record, instantiate the entity class, set its values using setter methods, and then use the Swift\Orm\EntityManager to persist and execute the operation. It is recommended to wrap the run() method in a try-catch block to handle potential errors.
    $movie = new Movie();
    $movie->setTitle( 'Foo bar' );
    $movie->setDescription( 'Movie about foo bar' );
    $movie->setReleased( new \DateTime() );
    $movie->setType( ConditionTypeEnum::OUTSIDE_TEMP );
    
    $this->entityManager->persist( $movie );
    
    try {
        $this->entityManager->run();
    } catch ( \Throwable $e ) {
        // handle error
    }
  9. Use ArrayCollection for Many-to-Many or One-to-Many relations

    In Swift ORM, ArrayCollection (an ArrayIterator implementation) is used to represent a list of entities for *Many relations. This allows for a simple interface to iterate over related entities. Collections must always be initialized within the entity's constructor to ensure they are available when the entity is instantiated.
    <?php declare( strict_types=1 );
    
    namespace App\Foo\Repository;
    
    use Swift\Orm\Entity\AbstractEntity;
    use Swift\Orm\Attributes\Entity;
    use Swift\Orm\Collection\ArrayCollection;
    
    #[Entity( table: 'movie_actors' )]
    class Actor extends AbstractEntity {
        protected ArrayCollection $movies;
    
        public function __construct() {
            // Collections must be initiated in the constructor
            $this->movies = new ArrayCollection();
        }
    }
  10. Add Entity Hooks using the Hook attribute

    The Hook attribute allows you to subscribe to specific entity events using a callable (such as a static method within the entity class). This provides a simple observer pattern to execute logic during the entity lifecycle.
    <?php declare( strict_types=1 );
    
    namespace Swift\Security\User\Entity;
    
    use Swift\Orm\Attributes\Behavior\Hook;
    use Swift\Orm\Attributes\Entity;
    use Swift\Orm\Attributes\Field;
    use Swift\Orm\Types\FieldTypes;
    use Swift\Orm\Entity\AbstractEntity;
    
    #[Entity( table: 'review' )]
    #[Hook(
        callable: [Review::class, 'onCreate'],
        events: [\Swift\Orm\Behavior\Event\Mapper\Command\OnCreate::class],
    )]
    #[Hook(
        callable: [Review::class, 'onUpdate'],
        events: [\Swift\Orm\Behavior\Event\Mapper\Command\OnUpdate::class],
    )]
    class Review extends AbstractEntity {
        #[Field( name: 'id', primary: true, type: FieldTypes::INT, length: 11 )]
        public int $id;
    
        public static function onCreate( \Swift\Orm\Behavior\Event\Mapper\Command\OnCreate $event ): void {
            // logic before review is created
        }
    
        public static function onUpdate( \Swift\Orm\Behavior\Event\Mapper\Command\OnUpdate $event ): void {
            // logic when review is updated
        }
    }