Giter VIP home page Giter VIP logo

yii-api's Introduction

Yii Framework

Yii Framework REST API Extension


โš ๏ธThe package is deprecated. All its functionality is now integrated into yiisoft/app-api.

yii-api's People

Contributors

bashkarev avatar brandonkelly avatar bscheshirwork avatar cebe avatar dependabot-preview[bot] avatar developeruz avatar dizews avatar dynasource avatar fantom409 avatar faryshta avatar johonunu avatar kids-return avatar klimov-paul avatar lav45 avatar leandrogehlen avatar lesha701 avatar machour avatar mohorev avatar mrarthur avatar pistej avatar qiangxue avatar rob006 avatar rustamwin avatar samdark avatar schmasterz avatar silverfire avatar softark avatar sonicgd avatar thenotsoft avatar xepozz 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  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  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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yii-api's Issues

[Yii 2.1] - Rest actions not setting headers right

What steps will reproduce the problem?

Create REST controller with model and call create action.

What's expected?

Get "created" response.

What do you get instead?

Throws error.

Additional info

{
	"name": "Exception",
	"message": "Call to a member function set() on array",
	"code": 0,
	"type": "Error",
	"file": "/home/nikola/Projects/yii2.1/vendor/yiisoft/yii2-rest/src/CreateAction.php",
	"line": 56,
	"stack-trace": [
		"#0 /home/nikola/Projects/yii2.1/vendor/yiisoft/yii2/base/Action.php(94): yii\\rest\\CreateAction->run()",
		"#1 /home/nikola/Projects/yii2.1/vendor/yiisoft/yii2/base/Controller.php(157): yii\\base\\Action->runWithParams(Array)",
		"#2 /home/nikola/Projects/yii2.1/vendor/yiisoft/yii2/base/Module.php(528): yii\\base\\Controller->runAction('create', Array)",
		"#3 /home/nikola/Projects/yii2.1/vendor/yiisoft/yii2/web/Application.php(103): yii\\base\\Module->runAction('post/create', Array)",
		"#4 /home/nikola/Projects/yii2.1/vendor/yiisoft/yii2/base/Application.php(396): yii\\web\\Application->handleRequest(Object(yii\\web\\Request))",
		"#5 /home/nikola/Projects/yii2.1/public/index.php(11): yii\\base\\Application->run()",
		"#6 {main}"
	]
}

Calling inside "CreateAction" and "OptionAction":

$response->getHeaders()->set(...

Instead of:

$response->getHeaderCollection()->set(...
Q A
Yii version 2.1
Yii REST version
PHP version 7.2
Operating system Arch Linux

yii\rest\UrlRule doesn't support route params.

This issue has originally been reported by @Faryshta at yiisoft/yii2#13968.
Moved here by @samdark.


What steps will reproduce the problem?

on config/main.php

'urlManager' => [
    'rules' => [
        [
            'class' => \yii\rest\UrlRule::class,
            'controller' => ['store/<store_id:\d+>/employee' => 'store-employee'],
        ],
    ],
],

What is the expected result?

use the StoreEmployeeController controller when accessing the route store/1/employee

What do you get instead?

http status 404 the rest rule is not even parsed.

Additional info

caused by line https://github.com/yiisoft/yii2/blob/master/framework/rest/UrlRule.php#L221 since it executes

strpos('store/1/employee', 'store/<store_id:\d+>/employee')

which obviously will return false. there is no work-around this. when removing this line (and the ending bracket) the url is parsed properly.

Bug in create action of \yii\rest\ActiveController

What steps will reproduce the problem?

Consider that you are using ActiveController and want to create an entity in your db.
When you send post request to create action and want check access of user that requested.

What's expected?

You expect that the model object in checkAccess method filled by user input but it's not.

What do you get instead?

The model object is null.

Additional info

Q A
Yii version 2.0.15.1
Yii REST version master
PHP version 7.1
Operating system Docker ubuntu 16

Please refer to this issue:
yiisoft/yii2#16812 (comment)

Send new model to checkAccess in yii\rest\CreateAction and yii\rest\UpdateAction

This issue has originally been reported by @vitalyspirin at yiisoft/yii2#16049.
Moved here by @cebe.


(recreated from yiisoft/yii2#5821 upon cebe request).

UpdateAction calls checkAccess() with existing model as a parameter. Why not to send an updated/created model as a third argument to checkAccess() (in $params)? The same goes for CreateAction.

Let's say I work with User model and property user_role can be set to "admin" by superadmin only. If regular user is trying to set that value then it's reasonable to throw Forbidden exception. I would consider checkAccess() function is a appropriate place to throw forbidden exception rather than in model validator (because user_role can have "admin" value set, it just has to be set by user with enough access permissions).

checkAccess is used to determine whether a user is allowed to call a specific action. This may depend on an existing model that has been created.

If it may depend on existing model values then it can also depend on newly sent model values.

Restrictions in creating a model should be covered by validation rules

As a workaround I check \Yii::$app->user in the model validation (to see whether logged in user is a superadmin - for text case described above) but \Yii::$app->user is a feature of web application and if to speak about proper layer separation it would be beneficial to decouple Model that it could be reused in console application.

Additional info

Q A
Yii version 2.0.14.1
PHP version 7.1.15-1
Operating system Ubuntu 14.04.5

Pass $query as a parameter to IndexAction::prepareDataProvider()

This issue has originally been reported by @vitalyspirin at yiisoft/yii2#15759.
Moved here by @samdark.


Currently prepareDataProvider() uses $modelClass::find() to instantiate a query. But let's say that I want a little bit different query. It would be convenient if I could pass $query as a parameter to this method with default value null. In this case if it's not passed then method can use find() method to initialize a query (to keep backward compatibility).

Basically I need all functionality of prepareDataProvider() except that one line of query instantiation:
https://github.com/yiisoft/yii2/blob/master/framework/rest/IndexAction.php#L114

I could override the method prepareDataProvider() and copy/paste its whole implementation from IndexAction class or I could override find() method for used model. I think that using dependency injection pattern is better. In that case I could override method prepareDataProvider(), generate my own query inside child method and pass it to parent method.

I am also wondering if passing $requestParams as a parameter (with default value null) would also be beneficial.

Q A
Yii version 2.0.14-dev
PHP version 7.1.12
Operating system Debian 7.3.0-1

Nested fields and expand in REST API

This issue has originally been reported by @ghost at yiisoft/yii2#8061.
Moved here by @samdark.


Facebook Graph API also uses fields and expand query parameters in REST APIs. Now Yii2 supports same but upto 1 level. Can we do nested fields like Facebook, for example:

GET graph.facebook.com/me?fields=albums.limit(5){name, photos.limit(2){name, picture, tags.limit(2)}},posts.limit(5)

In above example, my albums are limits to 5 only and again in each album only name and photos fields will be fetched with max 2 photos per album with again photos nested to give max 2 tags per photo. Along with albums, it will also give max 5 posts of the user.

Now limit(n) would be advance feature but I think nested expand is something easy to implement and really necessary feature to have.

PS: On separate note if you plan to support nested limit, you can also look into offset and sort on nested elements.

Item envelope in \yii\rest\Serializer

This issue has originally been reported by @FabrizioCaldarelli at yiisoft/yii2#7534.
Moved here by @samdark.


Hi all,
this is a possible improvement (not a bug).

I think that if I use collection evelope "items" in serializer, it could be useful to have single item envelope, as "item". In this way i'll have same structure of response.

Now i make this functionality extending ActiveController's actions() in this way:

    $actions['view'] = [
        'class' => 'api\components\CustomViewAction',
        'modelClass' => $this->modelClass,
        'checkAccess' => [$this, 'checkAccess'],
    ];

So in CustomViewAction i have

public function run($id) {
    $model = $this->findModel($id);
    if ($this->checkAccess) {
        call_user_func($this->checkAccess, $this->id, $model);
    }
    return ['item' => $model];
}

In this way i have single item or many items response in same way, using an envelope.

At the end, in $serializer's controller variable should be:

public $serializer = [
    'class' => 'yii\rest\Serializer',
    'collectionEnvelope' => 'items',
   'singleEnvelope' => 'item'
];

How to return empty object in json response?

What steps will reproduce the problem?

override function fields() in my Model like this

public function fields()
{
    return [
        'test' => function () {
              return someFailedQuery() ?? new \stdClass();
        }
    ]
}

and return the Model in Controller but get json response like this

{
    "test": []
}

What is the expected result?

if I don't use Model fields but define a array by myself

public function actionTest()
{
   return  [
            'a' => new \stdClass(),
        ];
}

got response

{
    "a": {}
}

this response really I need.

What do you get instead?

i found the problem in ArrayableTrait::toArray()
ArrayHelper::toArray will convert stdClass to empty array

so how can i get the json empty object in response?

Additional info

Q A
Yii version 2.0.8
PHP version 7.0.8
Operating system CentOS7

in ActiveDataFilter attributeMap applied before attribute validator.

If searchModel has some validator that change attribute value (like "trim" or "filter") and attributeMap is specified for that attribute then validator won't be applied since attribute is "normalized" first.

As I see in the function buildInternal() (of class \yii\data\ActiveDataFilter) normalize() is called before buildCondition():

https://github.com/yiisoft/yii2/blob/master/framework/data/ActiveDataFilter.php#L71

Value in attributeMap is on the left side of the expression in SQL WHERE clause. It would be convenient if I can change attribute value (through applying validator) before inserting it into the right side of SQL WHERE clause.

Additional info

Q A
Yii version 2.0.15.1?
PHP version 7.1.15
Operating system Ubuntu 14.04.5 LTS

Rename to yii-api

It is likely that this package will get code useful for RPC APIs as well as REST ones and mixed ones. May worth renaming it before release.

Feature Request: Nested Resources / Routes

In the Rails world they use "Resources" to describe nested routes. Here's a reference for further reading.
http://guides.rubyonrails.org/routing.html#nested-resources

It would be great to add this feature to Yii2.

class Magazine < ActiveRecord::Base
  has_many :ads
end

class Ad < ActiveRecord::Base
  belongs_to :magazine
end
resources :magazines do
  resources :ads
end

The above code gives you these routes out of the box

GET      /magazines/:magazine_id/ads
GET      /magazines/:magazine_id/ads/new
POST     /magazines/:magazine_id/ads

POST JSON input

What steps will reproduce the problem?

  1. Add component config as in quick-start.md
    'request' => [
        'parsers' => [
            'application/json' => 'yii\web\JsonParser',
        ]
    ]
  1. Create REST UserController as in quick-start.md

  2. sending a POST request with the user data in JSON format:

curl -X POST
https://api-dev.powerkernel.com/v1/user
-H 'accept: application/json'
-H 'cache-control: no-cache'
-H 'content-type: application/json'
-H 'postman-token: 69f05323-5c9e-88bc-140c-8eac38d62fb8'
-d '{"name": "My Name", "email": "[email protected]"}'

What's expected?

HTTP/1.1 201 Created
....

What do you get instead?

{
"name": "Unsupported Media Type",
"message": "",
"code": 0,
"status": 415,
"type": "yii\web\UnsupportedMediaTypeHttpException"
}

Additional info

Q A
Yii version 2.1-dev
Yii REST version @dev
PHP version 7.1
Operating system Ubuntu 16 LTS

Installation via composer fail

What steps will reproduce the problem?

Installation

What's expected?

Easy installation by adding

"yiisoft/yii2-rest": "~1.0.0"

to the require section of composer.json.

What do you get instead?

  • The requested package yiisoft/yii2-rest ~1.0.0 exists as yiisoft/yii2-rest[dev-master, 3.0.x-dev] but these are rejected by your constraint.

Additional info

Q A
Yii version 2
Yii REST version
PHP version
Operating system

REST JSONP response serialization

This issue has originally been reported by @andreykin at yiisoft/yii2#10943.
Moved here by @samdark.


I use JSONP as a response format when creating REST API:

public function actionIndex()
{
            \Yii::$app->response->format = \yii\web\Response::FORMAT_JSONP;
            $callback = \Yii::$app->request->queryParams['callback'];

            $searchModel = new RaspisanSearch();
            $data = $searchModel->search(\Yii::$app->request->queryParams);

            return ['data' => $data, 'callback' => $callback];
}

But actual response is serialized ActiveProvider:

callbackfunctionname({"query":{"sql":null,"on":null,"joinWith":null,"select":null,"selectOption":null,"distinct":null,"from":null,"groupBy":null,"join":null,"having":null,"union":null,"params":[],"where":null,"limit":null,"offset":null,"orderBy":null,"indexBy":null,"modelClass":"app\\models\\Raspisan","with":null,"asArray":null,"multiple":null,"primaryModel":null,"link":null,"via":null,"inverseOf":null},"key":null,"db":null,"id":null});

A problem orrurs in yii\rest\Serializer, which serialize() method don't understand ['data' => $data, 'callback' => $callback] format and return data without serialization.

public function serialize($data)
    {
        if ($data instanceof Model && $data->hasErrors()) {
            return $this->serializeModelErrors($data);
        } elseif ($data instanceof Arrayable) {
            return $this->serializeModel($data);
        } elseif ($data instanceof DataProviderInterface) {
            return $this->serializeDataProvider($data);
        } else {
            return $data;
        }
    }

Custom Link for Collection Result

I am thinking about how to sync UI in client side (mobile) and rest authorization. For the example, I have post entity. It can be access at domain.com/posts. There are 2 users, User A (can create post) and User B (can't create post). The problem is how client app (mobile) detects when to show or hide Create Post Button. This is what I mean by sync UI and Rest Authorization.

The solusion what I am thinking about is using link in domain.com/posts result. We can create new custom links at collection level service (domain.com/posts), not just for pagination.

{
    "data": [
        {
            "id": "1",
            "content": "....",
        },
        {
            "id": "2",
            "content": "....",
        },
        {
            "id": "3",
            "content": "....",
        }
    ],
    "_links": {
        "self": {
            "href": "http://localhost:8081/api/incidents?page=1"
        },
        "create": {
            "verb": "POST",
            "href" : "http://localhost:8081/api/incidents"
        }
    },
    "_meta": {
        "totalCount": 3,
        "pageCount": 1,
        "currentPage": 1,
        "perPage": 20
    }
}

For now, it just support link at entity level service (domain.com/posts/1), not collection level. I know with little customization, we can make it. But what if it is supported by default.

Inconsistent behavior for partially implemented Rest\ActiveController

Consider we have:

  1. One Rest\UrlRule with 1 controller.
  2. One Rest\ActiveController.

Suppose 2 scenarios:

  1. List only resource, implemented by overriding actions and removing all but index.
  2. Write only resource, implemented by overriding actions and removing all but create.

Now we go ahead and create (in)correct requests:

   GET /listonly --> 200
   POST /listonly --> 405 Method not allowed

    GET /writeonly --> 404 Page not found
    POST /writeonly -> 200 

The reason this happens is because beforeAction is not called for actions that can't be found.
Some issues arise from this

  1. ContentNegotiator is not used.
  2. A REST URL is an endpoint and it should not return 404 when 405 is more appropriate.

Not sure how to fix this, possible fixes include:

  1. Add event "beforeCreateAction" that gets called before attempting to create the action.
    --> This would allow VerbFilter and ContentNegotiator to do their work for not implemented actions.
  2. Add event "onInvalidRoute" that gets called before the exception, allowing a controller behavior to do some stuff to resolve the situation before falling back to the exception handler at the Application level.
  3. Add "beforeRunAction" event that gets called before runAction is called.

Any of these solutions would:

  1. Increase power of behaviors to do some stuff before failing.
  2. Not break BC in anyway.

Allowing string for comparison operator >,<,>=,<=

DataFilter doesn't allow string for comparison operator >,<,>=,<= by default.
However mysql, mssql and php all allows string comparisons.
ex : 'ball' < 'water' is true
Shouldn't DataFilter allow it too?

class DataFilter extends Model
{

    public $operatorTypes = [
        '<' => [self::TYPE_INTEGER, self::TYPE_FLOAT, self::TYPE_DATETIME, self::TYPE_DATE, self::TYPE_TIME,],
        '>' => [self::TYPE_INTEGER, self::TYPE_FLOAT, self::TYPE_DATETIME, self::TYPE_DATE, self::TYPE_TIME],
        '<=' => [self::TYPE_INTEGER, self::TYPE_FLOAT, self::TYPE_DATETIME, self::TYPE_DATE, self::TYPE_TIME],
        '>=' => [self::TYPE_INTEGER, self::TYPE_FLOAT, self::TYPE_DATETIME, self::TYPE_DATE, self::TYPE_TIME],
        '=' => '*',
        '!=' => '*',
        'IN' => '*',
        'NOT IN' => '*',
        'LIKE' => [self::TYPE_STRING],
    ];

    public function init()
    {
        // Manually adding string to comparison operators
        $this->operatorTypes['<'][] = self::TYPE_STRING;
        $this->operatorTypes['>'][] = self::TYPE_STRING;
        $this->operatorTypes['<='][] = self::TYPE_STRING;
        $this->operatorTypes['>='][] = self::TYPE_STRING;

        parent::init();
    }

What steps will reproduce the problem?

What is the expected result?

What do you get instead?

[{"field":"filter","message":"\"someString\" does not support operator \"lt\"."}]

Additional info

Q A
Yii version 2.0.14
PHP version
Operating system

How about enabling transaction in create/udpate/delete action?

I handling model relations by ActiveRecord::afterSave, but currently the create/udpate/delete action does not supports transaction, so I need to implement a wrapper to achieve that.

And I am thinking about that is there a better way make transaction as an option of Action, so that I do not need to implement my own action?

I got something like:

class CreateAction extends \yii\rest\CreateAction {

    public $enableTransaction = true;

    public function run()  {
        if ($this->enableTransaction) {
            return $this->safeRun();
        }
        return parent::run();
    }

    public function safeRun() {
        // begin transaction
        try {
              $model = parent::run();
              // commit transaction
              return $model;
        } catch (\Throwable $e) {
              // rollback transaction
        }
    }
}

Dependabot can't resolve your PHP dependency files

Dependabot can't resolve your PHP dependency files.

As a result, Dependabot couldn't update your dependencies.

The error Dependabot encountered was:

Your requirements could not be resolved to an installable set of packages.
  Problem 1
    - Installation request for yiisoft/yii-web ^3.0@dev -> satisfiable by yiisoft/yii-web[3.0.x-dev].
    - yiisoft/yii-web 3.0.x-dev requires psr/http-factory-implementation 1.0 -> no matching package found.
  Problem 2
    - Installation request for yiisoft/view ^3.0@dev -> satisfiable by yiisoft/view[3.0.x-dev].
    - yiisoft/view 3.0.x-dev requires psr/event-dispatcher-implementation 1.0.0 -> no matching package found.

Potential causes:
 - A typo in the package name
 - The package is not available in a stable-enough version according to your minimum-stability setting
   see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.
 - It's a private package and you forgot to add a custom repository to find it

Read <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.

If you think the above is an error on Dependabot's side please don't hesitate to get in touch - we'll do whatever we can to fix it.

View the update logs.

RESTFul About 404 error handling

This issue has originally been reported by @xutl at yiisoft/yii2#14775.
Moved here by @samdark.


What steps will reproduce the problem?

  1. open restful url http://localhost/api/users/1
    return 200 ok
  2. open restful url http://localhost/api/users/111111111
    return 404 this is normal
  3. When opening a non-existent URL e.g http://localhost/api/abcdefg
    Returned the html 404 page,He should return the same format as xml or json as in the second step.

What is the expected result?

Returns a formatted xml or json.

What do you get instead?

Additional info

Q A
Yii version 2.0.12
PHP version 7.1.6
Operating system centos 7.1

yii\rest\Serializer should apply with() on ActiveDataProvider query when "expand" is present

Rest Serializer does not pre-configures ActiveDataProvider query with relations when "expand" parameter is passed, resulting in the performance issue with SQL queries being fired for each model and each relation.

What steps will reproduce the problem?

Execute a REST call with the "expand" parameter to include relations in the result.

What is the expected result?

1 SQL query to get models, 1 SQL query for each relation in "expand" to get related records data.

What do you get instead?

1 SQL query to get models, 50 SQL queries for each relation in "expand" to get related records data.

Additional info

Q A
Yii version 2.0.14
PHP version 7.1
Operating system MacOS

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.