Git Product home page Git Product logo

oc-api-plugin's Introduction

API Framework for OctoberCMS

It's a plugin for OctoberCMS for you that want to create an extensible and easy to use API server.

Features

Installation

  1. Download this plugin and put to plugins directory (plugins/octobro/api).
  2. Run composer update on your project root directory.

Tips: if you want to follow this plugin, you can use this plugin as a submodule on your git project.

Usage

This plugin is a base for your application API. You should create your "API" plugin for your application.

Create Your Plugin

php artisan create:plugin Foo.Bar

In your Plugin.php file, we recommend you to put Octobro.API as plugin dependency.

class Plugin extends PluginBase
{
	public $require = ['Octobro.API'];
	

Define the REST API Routes

Create routes.php using this starter template.

Route::group([
	'prefix'     => 'api/v1',
	'namespace'  => 'Foo\Bar\ApiControllers',
	'middleware' => 'cors'
], function() {
	
	//	
	// Your public resources should be here
	//
	
});

Don't forget to change the Controllers namespace on your plugin.

Create Your App Resources

For example in an e-commerce application, we want to open the products catalog API.

Put the URL to your plugins/foo/bar/routes.php

Route::get('products', 'Products@index');
Route::get('products/{id}', 'Products@show');

Route::post('orders', 'Orders@store');

Create the plugins/foo/bar/apicontrollers/Products.php file.

<?php namespace Foo\Bar\ApiControllers;

use Octobro\API\Classes\ApiController;
use Foo\Bar\Models\Product;
use Foo\Bar\Transformers\ProductTransformer;

class Products extends ApiController
{
    public function index()
    {
        $products = Product::get();

        return $this->respondwithCollection($products, new ProductTransformer);
    }

    public function show($id)
    {
    	$product = Product::find($id);

    	return $this->respondwithItem($product, new ProductTransformer);
    }
}

Create The Transformers

Transformer will help you to transform data from a model object to set of array including relationship using include and exclude query.

For example in this case, we create the plugins/foo/bar/transformers/ProductTransformer.php

<?php namespace Foo\Bar\Transformers;

use Octobro\API\Classes\Transformer;
use Foo\Bar\Models\Product;

class ProductTransformer extends Transformer
{
    // Related transformer that can be included
    public $availableIncludes = [
    	'categories',
    	'brand',
    ];
    
    // Related transformer that will be included by default
    public $defaultIncludes = [
    	'categories',
    ];

    public function data(Product $product)
    {
        return [
            'id'          => (int) $product->id,
            'sku'         => $product->sku,
            'name'        => $product->name,
            'description' => $product->description,
            'price'       => $product->price,
            'sale_price'  => $product->sale_price,
            'image'       => $this->image($product->image),
            'gallery'     => $this->images($product->gallery),
            'created_at'  => date($product->created_at),
        ];
    }
    
    public function includeCategories(Product $product)
    {
        return $this->collection($product->categories, new CategoryTransformer);
    }
    
    public function includeBrand(Product $product)
    {
        return $this->item($product->brand, new BrandTransformer);
    }
}

With Scaffolding Command

You can also create a transformer using the scaffolding commands to speed up your development process.

Use octobro:transformer command to create a new transformer. The first parameter specifies the author and plugin name. The second parameter specifies the model name. Note that the model name must be written with its namespace and the backward slash used must be doubled.

php artisan octobro:transformer Foo.Bar Foo\\Bar\\Models\\Product

That's it! You're successfully created the API in easy way! There are ton of features that very usable for your scalable and extensible application.

Trying the API

We recommend you to use API client like Postman or Insomnia for easy testing.

Basic Call

GET http://example.com/api/v1/products

The response will be.

{
    "data": [
        {
            "id": 1,
            "name": "Sample Prouct",
            ...
        },
        ...
    ]
}

Using Include Query

GET http://example.com/api/v1/products?include=brand,categories

{
    "data": [
        {
            "id": 1,
            "name": "Sample Prouct",

            "brand": {
                "data": {
                    "id": 21,
                    "name": "Nike",
                    ...
                }
            },

            "categories: {
                "data": [
                    {
                        "id": 45,
                        "name": "Hot Product",
                        ...
                    },
                    {
                        "id": 8,
                        "name": "Shoes",
                        ...
                    }
                ]
            }
        }
    ]
}

Using Paginator

GET http://example.com/api/v1/products?page=2,number=20

{
    "data": [
        {
            "id": 1,
            "name": "Sample Prouct",
            ...
        },
        ...
    ],
    "meta": {
        "pagination": {
            "total": 1,
            "count": 1,
            "per_page": 20,
            "current_page": 2,
            "total_pages": 10,
            "links": {
                "previous": "http://example.com/api/v1/products?page=1",
                "next": "http://example.com/api/v1/products?page=3"
            }
        }
    }
}

Configuring Serializer

By default this plugin is using DataArraySerializer from Fractal. If you want to use another serializer, there are another options like ArraySerializer or JsonApiSerializer.

To change the serializer you can extend it on your own Plugin.php.

use Octobro\API\Classes\ApiController;
use League\Fractal\Serializer\JsonApiSerializer;

class Plugin extends PluginBase
{
    public $require = ['Octobro.API'];

    public function boot()
    {
    	ApiController::extend(function($controller) {
    		$controller->fractal->setSerializer(new JsonApiSerializer());
    	});
    }
}

Recommended Plugins

We are building another API-enabled plugins that can be used easily!

Extending Plugins

Need to extend the plugin? We can just add some lines to add the fields of data, or even creating or manipulating includes query.

In this example we want to extend ProductTransformer.php.

Adding Fields

// Add this on your plugin boot() method

ProductTransformer::extend(function($transformer) {

    // Add field one by one
    $transformer->addField('tags', function($product) {
        return $product->tags->toArray();
    });
    
    // Add field based on object attribute
    // In this case, if the Product has tax attribute ($product->tax)
    $transformer->addField('tax');
    
    // Wanna add more fields based on attributes?
    // You can put it all together
    $transformer->addFields(['url', 'color', 'is_recommended']);
});

Adding Includes

// Add this on your plugin boot() method

ProductTransformer::extend(function($transformer) {

    // For example it has reviews relation
    $transformer->addInclude('reviews', function($product) use ($transfomer) {
        return $transformer->collection($product->reviews, new ReviewTransfomer);
    });
    
    // Or if it has single relation
    $transformer->addInclude('brand', function($product) use ($transfomer) {
        return $transformer->item($product->brand, new BrandTransformer);
    });    
});

Composer Packages Used

License

The OctoberCMS platform is open-sourced software licensed under the MIT license.

oc-api-plugin's People

Contributors

aneksa avatar erwinade avatar prasiman avatar serkanbektas avatar triasrahman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oc-api-plugin's Issues

Double Relation Data

Hi there,

I like the implementation of this API idea for OC. I have an issue with a nested relation, it's showing up twice in a call. Once within the correct place, in this case items is a many relation of area but it's also appearing after the area object. See below.

Any idea what is wrong?

{
    "data": {
        "id": "1"
        "name": "Parent model"
     "areas": {
            "data": [
                {
                    "area": {
                        "id": "1",                      
                        "name": "an area",
                       "items": [
                            {
                                "id": "1",
                                "name": "an item",
                            }
                        ]
                    },
                    "items": {
                        "data": [
                            [
                                {
                                    "id": "1",
                                     "name": "an item",
                                }
                            ]
                        ]
                    }
               }
           ]
       }
   }
}

My Transformer classes call the relation includes like this.

    public $defaultIncludes = [
        'areas'
    ];

    public function data(Parent $parent)
    {
        return [
            'id'         => $parent->id,
        ];

    }

    public function includeAreas(Parent $parent)
    {
        return $this->collection($parent->areas, new AreasTransformer);
    }

public $defaultIncludes = [
        'items'
];

public function data(Areas $areas)
{
    return [
         $areas
    ];
}

public function includeItems(Areas $areas)
    {
        return $this->collection($areas->items, new ItemsTransformer);
    }
public $defaultIncludes = [];

public function data(Items $items)
{
    return [
         $items
    ];
}

Authentication ?

Hello, the plugin seems to be very fine.
How would it be possible to have authenticated (JWT) requests ? Thanks

Problem Extending Transformer

Got the following error returned from api when creating transformer following the given example:

"error": {
    "code": "INTERNAL_ERROR",
    "http_code": 500,
    "message": "Cannot override final method Octobro\\API\\Classes\\Transformer::transform()"
},

Artisan commands

I've just installed your plugin and was trying the artisan command to create a transformer.
"There are no commands defined in the "octobro" namespace" is what I am getting. The plugin was installed by the backend plugin manager so perhaps that's why no artisan commands are registered?

Thank you in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.