2017 © Pedro Peláez
 

symfony-bundle api-bundle

A Symfony bundle that generates webservices based on entities list.

image

orbitale/api-bundle

A Symfony bundle that generates webservices based on entities list.

  • Sunday, May 15, 2016
  • by Pierstoval
  • Repository
  • 2 Watchers
  • 2 Stars
  • 0 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 1 Forks
  • 1 Open issues
  • 3 Versions
  • 0 % Grown

The README.md

:warning: This bundle is abandoned (it was mostly a PoC). Please use API Platform instead.

SensioLabsInsight Build Status Coverage Status, (*1)

Orbitale ApiBundle

Allows the developer to create simple webservices based on an entities list in configuration., (*2)

Installation

With Composer, (*3)

Just write this command line instruction if Composer is installed in your Symfony root directory :, (*4)

composer require orbitale/api-bundle

I recommend to use Composer, as it is the best way to keep this repository update on your application. You can easily download Composer by checking the official Composer website, (*5)

Initialization

You need to initiate some settings to make sure the bundle is configured properly., (*6)

  1. First, register the required bundles in the kernel:, (*7)

    <?php
    # app/AppKernel.php
    class AppKernel extends Kernel
    {
        public function registerBundles() {
            $bundles = array(
                // ...
                new Orbitale\Bundle\ApiBundle\OrbitaleApiBundle(),
    
    
  2. Import the routing in your application:, (*8)

    # app/config/routing.yml
    orbitale_api:
        resource: "@OrbitaleApiBundle/Controller/"
        type:     annotation
        prefix:   /api/
    

    The prefix is up to you, but it's important that the app has to be solitary in its relative path, for it to work in the best way., (*9)

  3. Done ! The rest is all specific configuration for your application.

Usage

Add your first entity in the config:, (*10)

# app/config/config.yml
orbitale_api:
    services:
        posts: { entity: AppBundle\Entity\Post }

Run your server:, (*11)

$ php app/console server:run

Navigate to its generated url http://127.0.0.1/app_dev.php/api/post., (*12)

Now you should see something like this:, (*13)

{"posts":[]}

If you do see this, it means that the API generator is working !, (*14)

HTTP methods

The generator handles GET, POST (update), PUT (insert) and DELETE HTTP methods., (*15)

GET routes

  • orbitale_api_cget : /{serviceName}, (*16)

    This route allows to get a collection of objects of the specified entity., (*17)

    The received collection has the same key as the serviceName, and is an array of objects., (*18)

  • orbitale_api_get : /{serviceName}/{id}, (*19)

    This route retrieves a single object with its primary key (even if this primary key is not called id). The received element will have the same key as the serviceName but with removed trailing 's' at the end of it (for example, posts will become post)., (*20)

    All the received attributes in the object will follow your ExclusionPolicy and different Expose or Exclude settings in the jms_serializer., (*21)

    If you need more information about exposing or not some fields, you can check JMSSerializer's documentation, (*22)

  • orbitale_api_get_subrequest : /{serviceName}/{id}/{subElement}, (*23)

    This is the great point of this Api generator., (*24)

    This route can retrieve any element recursively depending on three parameters:, (*25)

    • The parameter has to be a valid entity attribute.
    • If the attribute is a collection, you can fetch one element in this collection by appending its primary key.
    • The value must not be null (or it'll return an empty value).

    For example, if your Page entity has a title attribute, you can type this url: http://127.0.0.1:8000/api/pages/1/title., (*26)

    And you may see something like this:, (*27)

    {"page.1.title":"Default page"}
    

    As the subRequest is managed recursively, you really can navigate in a complex object like this: http://127.0.0.1:8000/api/pages/1/children/2/category/name. It will then retrieve datas in the specified order :, (*28)

    • Get the page element with primary key 1.
    • Get its element children, which is a collection of Page.
    • Retrieve the one with the primary key 2.
    • Get the Page 2's category object.
    • Get the category name.

    The output may look like this:, (*29)

    {"page.1.children.2.category.name": "Default category"}
    

    The object's key is the compilation of your request, so you can check whether it exists in your code, and if it does, it means that it's a valid object., (*30)

POST and PUT routes

The POST route is only used to UPDATE datas. The PUT route is only used to INSERT datas., (*31)

Basically, the PUT route works the same than the POST route, but it won't merge any entity in the database. It will instead fill an empty entity, validate it, and if the object is valid, persist it., (*32)

  • POST: orbitale_api_post : /{serviceName}/{id}
  • PUT: orbitale_api_put : /{serviceName}

The route will first search for an entity of serviceName with primary key id., (*33)

The json object

The API will search for a json parameter in POST datas. If it's a string, it's automatically transformed into a Json object., (*34)

This json object is a transposition of your entity serialized object, with its values., (*35)

It means that you can use your entity attributes as they're shown by the Api generator. It will simply merge (if POST) or fill an empty object (if PUT) to the database object with your json object, so it won't modify other parameters., (*36)

The mapping object

Additionally, the Api will search for a mapping object. This object is mandatory, and it defines all the fields you want to, (*37)

For example, if you only want to modify a Page title attribute, you can use this json object:, (*38)

{ "json": { "title": "New title !" }, "mapping": { "title": true } }

Then, you will change the title, and you won't modify any other data directly., (*39)

The entire object will be then sent to validation through the Symfony's validator service, so you can see if the object is wrongly updated or not, by simply using your usual validation annotations or files., (*40)

If the object is not valid, the API will send you all the error messages sent by the validator service, for you to handle them in front (or back, depending on how you manage to use this bundle)., (*41)

The output is the newly updated or inserted object., (*42)

Mapping-specific behavior

Sometimes you use camelCase, sometime snake_case, and jms_serializer can be configured differently in different apps., (*43)

This is why some attributes may have their name changed through the serialization process., (*44)

One simple case :, (*45)

In your Page entity, you have a ManyToOne relationship with a Category object., (*46)

Your mapping looks like this:, (*47)

# AppBundle\Entity\Page.php
// ...
    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Category")
    */
    protected $pageCategory;

When retrieving a Page object with the API, you'll see this :, (*48)

{ "page": { "title": "Page title", "page_category": { "id": 1, "name": "Default category" } } }

This can have some breaks, does it?, (*49)

Then, when you send your JSON object to any of the PUT or POST methods, you'll have to tell the API that the fields have different names., (*50)

For example, in a POST request:, (*51)

{
    "json": { "page_category": { "id": 1, "name": "Sefault category" } },
    "mapping": { "page_category": { "objectField": "pageCategory" } }
}

With this special mapping for page_category, you will tell the API that the page_category json attribute corresponds to a pageCategory attribute in your Doctrine entity., (*52)

Relationships

As no automatic cascading operation is made, you'll have to specify it in your Entity mapping., (*53)

Plus, the object must be an existing object, or you can have some unexpected behavior., (*54)

Secure your API

In the configuration reference you may see a allowed_origins attribute., (*55)

This attribute is used to check whether the asker has rights to view this API or not. It's especially useful to refuse connections from some IP addresses, and from unwanted AJAX requests (CORS is not managed, you'll have to use another bundle for that)., (*56)

By default, in dev environment, localhosts are automatically added to the allowed_origins array., (*57)

The current server IP address is also added to the allowed_origins, for you to make requests to your own API from your own server., (*58)

You can add other IPs or domain names in this attribute like this:, (*59)

# app/config/config.yml
orbitale_api:
    allowed_origins: 
        - 1.2.3.4
        - my.domain.com

This is a basic security system. If you want more security, you'll have to extend the ApiController and override the checkAsker method, and also change the routing namespace to your own controller., (*60)

The Versions

01/01 2016
23/06 2015

dev-refactor_tests

dev-refactor_tests

A Symfony bundle that generates webservices based on entities list.

  Sources   Download

MIT

The Requires

 

The Development Requires

api entity symfony webservices entities