zfcampus / zf-apigility Goto Github PK
View Code? Open in Web Editor NEWLicense: BSD 3-Clause "New" or "Revised" License
License: BSD 3-Clause "New" or "Revised" License
For example, i have a table called "student" with id, name, phone, nickname four fields. I have create two field name (name, phone) in rest service configuration. However, it will return all the four fields instead of the configured fields (name, phone). May i know is it the expected case. If yes, could i have a pull request on it?
Hi All,
A quick bug report, steps to reproduce:
Create a new API in admin panel
Create a new rest service inside API called "list"
The word "list" conflicts with the PHP keyword and stops the admin panel from working.
Might be worth filtering out PHP keywords on anything capable of generating a class or namespace with just that word (http://www.php.net/manual/en/reserved.keywords.php).
It was requested I create an example of an implementation of https://github.com/TomHAnderson/soliantconsulting-apigility
Here it is: https://github.com/etreedb/etreedb-api
There are detailed installation instructions in the README.md
This showcases the Admin implementing Resource generation from Doctrine entities and the supporing Server class but does not use the Client.
swagger-php provides a fairly simple means of generating Swagger documentation for restful APIs.
Apigility should provide this form of documentation if required, since many will be familiar with it already.
Usually, DB-connected services are created on databases that already exist. So, the DB schema is already known and Apigility can automatically configure the DB columns as fields in the REST service. Apigility can also automatically configure some attributes of the fields, e.g. if the field is required, or create a validator that ensures an integer input, etc.
At the moment, after creating the DB-connected service, I have to edit it and add all these fields myself, which is error prone. I have to look at the DB schema and type the exact column names as field names.
This improvement will bring this RAD feature one step forward.
Hi,
I need access to the OAuth2 Server object from my controller, in order to get some useful information such as the provided access token.
This way I can get information about the user that is making the request.
How can I do this? Can't find any useful documentation regarding this.
Thank you
Hi,
I have just installed Apigility using composer as outlined in the README.md file, put it in development mode and disabled OpCache, and open Apigility. So far, so good.
I then wanted to create a new DB Adapter, clicked, filled out the required details and when I clicked on Create DB Adapter -- nothing happened.
Checking the JS console, I see the following:
POST http://example.com/apigility/api/db-adapter 500 (Internal Server Error) vendor-angular.js:2
(Changed my domain above to example.com)
Any idea what may be the problem and how to fix it? There is nothing related in the Apache error log.
This is running on Ubuntu 13.10 with Apache webserver.
Thanks,
Golan.
I have been trying to install Apigility with the following command:
php -r "readfile('https://apigility.org/install');" | php
The installation runs but at the end I am getting this error:
Install Apigility
Installation complete.
Running PHP internal web server.
Open your browser to http://localhost:8888, Ctrl-C to stop it.
[Sun Jul 06 07:35:37 2014] Failed to listen on 0:8888 (reason: php_network_getaddresses: getaddrinfo failed: No such host is known. )
I have tried the installation on two different computers and I get the same error.
Thank you!
Steps
ER
AR
How to reproduce:
array(
...
'input_filter_specs' => array(
...
0 => array(
'name' => 'name',
'required' => true,
'filters' => array(
0 => array(
'name' => 'Zend\\Filter\\StringToUpper',
'options' => array(),
),
),
'validators' => array(),
),
{
"name" : "This string should be filter to upper"
}
Resource::create()
dump $data
class stdClass#162 (11) {
public $name =>
string(37) "This string should be filter to upper"
The field name is not string to upper.
Thanks.
We're building an API over a symfony2 app. The API invokes symofiny services which return symfony entities.
The thing is working ok, but after a runtime error in the symfony app, calls to API endpoints keep returning an entity annotation error even when the error is solved. After some days getting this error I think the message is actually not relevant, it was only a simple error in the entity
{
"file": "/var/www/my-api/public/index.php",
"line": 38,
"function": "run",
"class": "Zend\\Mvc\\Application",
"type": "->",
"args": []
}
],
"type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
"title": "Internal Server Error",
"status": 500,
"detail": "[Semantical Error] The annotation \"@Doctrine\\ORM\\Mapping\\Entity\" in class App\\UserBundle\\Entity\\Usuario does not exist, or could not be auto-loaded."
}
To reproduce this issue you can force a runtime error in the symfony entity (in my case it was using $var->attr
instead of $this->attr
), maybe entity needs to be annotated to reproduce same environment.
This is my fetch nethod, the one which keeps returning the error:
public function fetch($id)
{
$usuario = $this->userServiceSymfony->getUser($this->doctrine, $id);
// return $usuario->getArrayCopy();
return array('id' => $usuario->getId(),
'nombre' => $usuario->getNombre(),
'apellidos' => $usuario->getApellidos(),
'fechanacimiento' => $usuario->getFechanacimiento(),
'telefono' => $usuario->getTelefono(),
'campaignid' => $usuario->getCampaignid(),
'email' => $usuario->getEmail(),
'lastlogin' => $usuario->getLastLogin(),
);
}
Yesterday I was only able to recover from this error with a hard reset of a very previous commit, today, after some improvements I found the error again.
I've been thinking it would be nice to have global setting to prefix all API's build using Apigility. This would make Apigility modules being more portable between projects - e.g. when you deploy Apigility server on it's own (e.g. APIs are available under api.example.com) or you use Apigility modules within another application (example.com/api).
This could be done by injecting Api related routes into general application router.
Currently we create routes under 'router'->'routes' config. My quick suggestion would be to move this into 'api-router'->'routes' or just 'api-routes' config array.
What do you think?
please disable the code:
/vendor/zfcampus/zf-hal/src/Plugin/Hal.php
/*
if (!$id) {
return new ApiProblem(
422,
'No entity identifier present following entity creation.'
);
}
*/
I have two entities SchemaType and SchemaProperty, and they have a Many to Many associations to each other.
I query the entity SchemaType with DQL, in the command line, check the DQL using 'vendor/bin/doctrine-module orm:run-dql ...', it returns the object with all the associations loaded properly.
In resouce class, i run the same query and return the query object. In the response json, normal fields filled with right value, but assiaciations' fields all displays empty '[]'.
I'm using Doctrine for implementing code based REST service.
And it's work fine, while i'm not try use query in my entity Doctrine repository, which uses TWO from.
Than i can't use Doctrine pagination adapter, because error
Cannot count query which selects two FROM components, cannot make distinction
For example - i have some avia
service. When i'm use it, just create some query with query builder and than use Doctrine pagination.
$query = $this->repository->{$this->searchMethodName}($params);
$doctrinePaginator = $this->repository->getPaginationAdapterDoctrine($query);
$cityCollection = new $this->collectionPrototype($doctrinePaginator);
use DoctrineORMModule\Paginator\Adapter\DoctrinePaginator as PaginatorAdapter;
use Doctrine\ORM\Tools\Pagination\Paginator as ORMPaginator;
public function getPaginationAdapterDoctrine($query)
{
return new PaginatorAdapter(new ORMPaginator($query));
}
In this example
$this->collectionPrototype = "AviaCollection"
that generated by Apigility
namespace Api\V1\Rest\Avia;
use Zend\Paginator\Paginator;
class AviaCollection extends Paginator
{
}
So, Apigility say i'm must implement AdapterInterface|AdapterAggregateInterface $adapter
and pass it to collection constructor. But in my case i can't, becouse i need 2 from selects in query and Doctrine pagination don't work with error.
Cannot count query which selects two FROM components, cannot make distinction
How can i implement code connected service with Doctrine with Adigility with custom query?
Hi,
I have created several fields for input filter validation. For each field validator has some messages if that fails. Upon failed validation the messages never output to the json. Only the error_message
in the field is rendered.
The whole module.config.php is here
https://gist.github.com/shadow-fox/e9b679ebcc651ddea1cc
JSON request to http://api.someserver.com/user [POST]
{
"username" : "123123",
"password" : "ther",
"firstname" : "blah231",
"lastname" : "here21331",
"email" : "abcdefefefe"
}
And the results If validation fails.
{
"validation_messages": {
"username": [
"Username can't be empty."
],
"email": [
"Email can't be empty."
],
"firstname": [
"Firstname can't be empty."
],
"lastname": [
"Lastname can't be empty."
]
},
"type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
"title": "Unprocessable Entity",
"status": 422,
"detail": "Failed Validation"
}
When the Zend Developer Tools (The toolbar) is active the calls that are protected with authorization/authentication (OAuth) do not show a 403 unauthorized but give access to the resource without any form of authentication.
Hello folks.
I was wondering to use this module with doctrine and I know we have an option to create a new rest service code based.
Imagining I already have a module with a service layer with all my business logic, including my own fetchAll bringing only the records and columns I desire, is there any possibility to use apigility together with this serviceLayer?
If so, Do I still need to use the apigility Entity file? (just remebering I already have my entities because I use doctrine).
All the Best
Wesley
Currently there is no check for the return value of json_encode() call and if the encoding fails, it results in an empty response with status 200 OK.
json_encode() returns false
on failure (as documented here: http://php.net/manual/en/function.json-encode.php) so it would be good to check the return value and throw some "JsonEncodeException" etc. if the encoding has failed. This would allow the developer to debug the issue more easily.
More info about my specific issue in the mailing list discussion here: https://groups.google.com/a/zend.com/forum/#!topic/apigility-users/zE5GpwR4NBI
The header with the challenge is not present when the server responds with unauthorized
or unauthenticated
. There is a particular reason for this?
The header is present only if the response has a status code like 20*.
If you post an empty body into a REST endpoint, a crash/stack trace happens when the ContentValidationListener (zf-contentvalidation) tries to set the data into the validator (line 150). The Zend\InputFilter\BaseInputFilter setData method throws an uncaught exception if $data is not an array and not Traversable. This cascades all the way back up and ends up with an html stack-trace instead of a nice json (or appropriate) error message like you get if the json is invalid.
I just installed apigility (last commit "Merge branch 'hotfix/40'") on Windows 7 in a XAMPP envirionment and started the php webserver.
After that I create an API "MyAPI" which worked and than create a code-connected REST service "MyRestCC01" which throws and error "500 Internal Server Error". The service is nevertheless created.
The details of the error response is
{"status":500,"title":"Unexpected error","describedBy":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html","detail":"Missing parameter "controller_service_name"","details":{"code":0,"message":"Missing parameter "controller_service_name"","trace":"#0
D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\Mvc\Router\Http\Segment.php(313): Zend\Mvc\Router\Http\Segment->buildPath(Array, Array, true, true, Array)\n#1 D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\Mvc\Router\Http\Segment.php(409): Zend\Mvc\Router\Http\Segment->buildPath(Array, Array, false, true, Array)\n#2
D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\Mvc\Router\Http\Part.php(189): Zend\Mvc\Router\Http\Segment->assemble(Array, Array)\n#3 D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\Mvc\Router\Http\TreeRouteStack.php(326): Zend\Mvc\Router\Http\Part->assemble(Array, Array)\n#4
D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\Mvc\Router\Http\Part.php(202): Zend\Mvc\Router\Http\TreeRouteStack->assemble(Array, Array)\n#5 D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\Mvc\Router\Http\TreeRouteStack.php(326): Zend\Mvc\Router\Http\Part->assemble(Array, Array)\n#6
D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\Mvc\Router\Http\Part.php(202): Zend\Mvc\Router\Http\TreeRouteStack->assemble(Array, Array)\n#7 D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\Mvc\Router\Http\TreeRouteStack.php(326): Zend\Mvc\Router\Http\Part->assemble(Array, Array)\n#8 D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\Mvc\Router\Http\Part.php(202): Zend\Mvc\Router\Http\TreeRouteStack->assemble(Array, Array)\n#9 D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\Mvc\Router\Http\TreeRouteStack.php(347): Zend\Mvc\Router\Http\Part->assemble(Array, Array)\n#10 D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\View\Helper\Url.php(100): Zend\Mvc\Router\Http\TreeRouteStack->assemble(Array, Array)\n#11 [internal function]: Zend\View\Helper\Url->__invoke('zf-apigility-ad...', Array, Array, true)\n#12 D:\DEV-ML\htdocs\api\vendor\zfcampus\zf-hal\src\ZF\Hal\Plugin\Hal.php(534): call_user_func(Object(Zend\View\Helper\Url), 'zf-apigility-ad...', Array, Array, true)\n#13 D:\DEV-ML\htdocs\api\vendor\zfcampus\zf-hal\src\ZF\Hal\Plugin\Hal.php(558): ZF\Hal\Plugin\Hal->fromLink(Object(ZF\Hal\Link\Link))\n#14 D:\DEV-ML\htdocs\api\vendor\zfcampus\zf-hal\src\ZF\Hal\Plugin\Hal.php(591): ZF\Hal\Plugin\Hal->fromLinkCollection(Object(ZF\Hal\Link\LinkCollection))\n#15 D:\DEV-ML\htdocs\api\vendor\zfcampus\zf-hal\src\ZF\Hal\Plugin\Hal.php(451): ZF\Hal\Plugin\Hal->fromResource(Object(ZF\Hal\Resource))\n#16 D:\DEV-ML\htdocs\api\vendor\zfcampus\zf-hal\src\ZF\Hal\View\HalJsonRenderer.php(122): ZF\Hal\Plugin\Hal->renderResource(Object(ZF\Hal\Resource))\n#17 D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\View\View.php(205): ZF\Hal\View\HalJsonRenderer->render(Object(ZF\Hal\View\HalJsonModel))\n#18 D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\Mvc\View\Http\DefaultRenderingStrategy.php(102): Zend\View\View->render(Object(ZF\Hal\View\HalJsonModel))\n#19 [internal function]: Zend\Mvc\View\Http\DefaultRenderingStrategy->render(Object(Zend\Mvc\MvcEvent))\n#20 D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\EventManager\EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))\n#21 D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\EventManager\EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('render', Object(Zend\Mvc\MvcEvent), Array)\n#22 D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\Mvc\Application.php(349): Zend\EventManager\EventManager->trigger('render', Object(Zend\Mvc\MvcEvent))\n#23 D:\DEV-ML\htdocs\api\vendor\zendframework\zendframework\library\Zend\Mvc\Application.php(324): Zend\Mvc\Application->completeRequest(Object(Zend\Mvc\MvcEvent))\n#24 D:\DEV-ML\htdocs\api\public\index.php(38): Zend\Mvc\Application->run()\n#25 {main}"}}
Thanks for your help,
Markus
I've created 3 database tables. City, State, Country. Inserted one row for each of them. Created those 3 db connected rest services, but when i try to use the get method for State, doesn't matter if using the id param or not, it returns empty response with http 200.
Didn't modify anything to any of the services, and the other ones are working. Also tried to delete it and create again. My guess is that its some bug with the service name (State might be a reserved word or something).
Apart from that, couldn't figure out what is going on. Tried to var_dump $collection before the return of RestController and it actually returns the expected collection with one result in it, but couldn't figure out to where this object is returned.
Figured it out.
json_encode is failing in https://github.com/zendframework/zf2/blob/master/library/Zend/Json/Json.php#L119
with message:
Malformed UTF-8 characters, possibly incorrectly encoded.
which then i figured out that was because my incorrect database adapter charset configuration.
Anyway, it would be very nice to get this json_encode error as a ApiProblem instead of a blank response with http 200.
So installing techniques do not work either.
curl -sS http://apigility.org/install | php
or
php -r "readfile('http://apigility.org/install');" | php
In Chrome when we return WWW-Authenticate:Basic and 401 status in xhr request it show a popup, to not show the popup must return x-base.
Sorry about my english
Perhaps I'm doing this incorrectly, but I'd like to customize the error coming from this particular validator.
2 => array(
'name' => 'ZF\\ContentValidation\\Validator\\Db\\NoRecordExists',
'options' => array(
'field' => 'myfield',
'table' => 'my_table',
'adapter' => 'MyDB',
),
'error_message' => 'This data already exists.',
),
but when executed I'm seeing :
"validation_messages": {
"myfield": {
"recordFound": "A record matching the input was found"
},
If error_message isn't correct, that's fine but perhaps then it should be clarified in a demo / instruction.
Hello folks.
I've just created and API and a Rest Service code based and I can see that 3 files were created:
In the resource I can see We have the methods create, delete, etc.
My question is how can I use a kind of serviceLocator to access a service?
Add the ability to ensure database/schema is included in table name.
Hello, we need to give a third party body api documentation for them to consume our api but do not want now to allow them to see 'live' generated documentation.
how can we generate a stitic version of doc generated by apigility?
thx in advance.
In my config I set $config['zf-hal']['render_collections'] = false in order to bandaid a problem with recursive entity reference. However, when I do so, the Apigility admin stops working. The main section of /apigility/ui#/api is blank. The javascript console displays this error:
TypeError: Cannot call method 'pop' of undefined
at http://localhost:8080/zf-apigility-admin/js/app.js:1:5390
at Array.forEach (native)
at Object.f [as forEach] (http://localhost:8080/zf-apigility-admin/js/vendor-angular.js:1:1005)
at f (http://localhost:8080/zf-apigility-admin/js/app.js:1:5326)
at new <anonymous> (http://localhost:8080/zf-apigility-admin/js/app.js:1:5869)
at d (http://localhost:8080/zf-apigility-admin/js/vendor-angular.js:1:15787)
at Object.e [as instantiate] (http://localhost:8080/zf-apigility-admin/js/vendor-angular.js:1:15899)
at http://localhost:8080/zf-apigility-admin/js/vendor-angular.js:1:32078
at q (http://localhost:8080/zf-apigility-admin/js/vendor-angular.js:4:23001)
at A (http://localhost:8080/zf-apigility-admin/js/vendor-angular.js:4:23362)
Not really sure if I should be posting this in zf-apigility or zf-hal, but they're both zfcampus modules so I'll let you guys sort it out.
My issue is with line 146 in ZF\MvcAuth\Authentication\DefaultAuthenticationListner
if ($this->oauth2Server->verifyResourceRequest($oauth2request))
The verifyResourceRequest method has a $scope parameter that isn't getting passed to the oauth server in this line so it is assumed that any scope is vaild for this request as $scope defaults to null.
I'm aware that at this point it would be necessary to identify what scope should be required for this request and pass it through to the verifyResourceRequest method so that the token can be checked for this scope.
Is the DefaultAuthenticationListner designed to be overridden so that I can implement functionality to check which scope is required for this request or am I missing something?
I'm porting a ZF2 based API over to Apigility, and we use an 'InArray' validator with a haystack option.
'validators' => array(
array(
'name' => 'InArray',
'options' => array(
'haystack' => array('0', '1')
)
),
),
I am not seeing this option 'haystack' when editing inside the admin tool. did this get moved?
Hello folks.
I created a new REST service and when i try to change the identifier name (like: status_id) it does not work.
Hi,
Within Apigility I only see options (so it seems) for a single primary key column.
REST Parameters:
Route Identifier Name
statusId
Entity Identifier Name
id
Does Apigility support more than one identifier field at this moment (thus a composite primary key)?
Let's say I've got a user resource where a user may have zero or more related addresses. An address cannot exist without a user entity. Let's say that I want to be able to query for a user's addresses by hitting the following URL:
/users/:id/addresses
What would be the best way to do this with Apigility?
Per the mailing list, it may make sense to pass the $data
argument of DbConnectedResource::fetchAll()
to the TableGatewayPaginator
(as the second argument, forming the $where
clause).
However...
It may also make sense to map query string parameters to the clause they should be used in. Zend\Paginator\Adapter\DbTableGateway
has the following arguments:
$tableGateway
- already being passed, for obvious reasons.$where
- to create the WHERE clause$order
- to sort the returned values$group
- for GROUP BY clauses$having
- for HAVING clausesEach of the latter four can take an associative array of arguments.
As such, this feature should likely not pass $data directly, but instead map parameters to arguments... which means a related UI feature.
I've put some HTML tags in the "REST service description" field, so after Save I've checked http://mydomain.com/apigility/documentation/MyService-v1 and found HTML tags displayed like:
Another paragraph
Hi,
I want to use Apigilty for our new api, but I have a problem with embedded collections.
Is it possible to render an embedded different collection type?
Like this:
$availabilityEntity = new AvailabilityEntity();
$availabilityEntity->id = 42;
$availabilityCollection = new AvailabilityCollection(new \Zend\Paginator\Adapter\ArrayAdapter(array($availabilityEntity)));
$entity = new ServiceAddressEntity();
$entity->id = 42;
$entity->productAvailabilityCollection = $availabilityCollection;
return new ServiceAddressCollection(new \Zend\Paginator\Adapter\ArrayAdapter(array($entity)));
But I always an 500 error with missing serviceaddress_id. It seems the hal plugin wants to render the links with the routing helper. The helper searches for the id from the main collection and cannot find it.
#0 /var/www/thorin/vendor/zendframework/zendframework/library/Zend/Mvc/Router/Http/Segment.php(409): Zend\Mvc\Router\Http\Segment->buildPath(Array, Array, false, false, Array)
#1 /var/www/thorin/vendor/zendframework/zendframework/library/Zend/Mvc/Router/Http/TreeRouteStack.php(351): Zend\Mvc\Router\Http\Segment->assemble(Array, Array)
#2 /var/www/thorin/vendor/zendframework/zendframework/library/Zend/View/Helper/Url.php(100): Zend\Mvc\Router\Http\TreeRouteStack->assemble(Array, Array)
#3 [internal function]: Zend\View\Helper\Url->__invoke('product.rest.av...', Array, Array, true)
#4 /var/www/thorin/vendor/zfcampus/zf-hal/src/Plugin/Hal.php(610): call_user_func(Object(Zend\View\Helper\Url), 'product.rest.av...', Array, Array, true)
#5 /var/www/thorin/vendor/zfcampus/zf-hal/src/Plugin/Hal.php(634): ZF\Hal\Plugin\Hal->fromLink(Object(ZF\Hal\Link\Link))
#6 /var/www/thorin/vendor/zfcampus/zf-hal/src/Plugin/Hal.php(667): ZF\Hal\Plugin\Hal->fromLinkCollection(Object(ZF\Hal\Link\LinkCollection))
#7 /var/www/thorin/vendor/zfcampus/zf-hal/src/Plugin/Hal.php(525): ZF\Hal\Plugin\Hal->fromResource(Object(ZF\Hal\Entity))
You can join tables in apigility?
Hi there,
How to get authenticated Indentity inside REST resource?
Thanks
Take Apigility out of the equation for a moment...
Default Input Filter Behavior:
$inputFilter = new InputFilter();
$inputFilter->add(array(
'name' => 'foo',
'required'=>true,
'allow_empty'=>false,
'filters'=>array(
array('name'=>'StripNewLines'),
array('name'=>'StripTags'),
array('name'=>'StringTrim'),
),
'validators'=>array(
array('name'=>'StringLength',
'options'=>array(
'min'=>3,
),
),
),
)
);
$inputFilter->setData(array('foo'=>' bar<a>', 'baz'=>'boo'));
$inputFilter->isValid(); // returns true
$inputFilter->getValues(); // returns array('foo'=>'bar')
Even though we are passing a value for a field that was not defined, the input filter is valid and returns only the data that it has instructions for. This is expected behavior.
Now, let's say you compose the same input filter via Apigility for an API endpoint and submit the same array of data. The API will respond with a status 400 (Bad Request) with the error message of: Unrecognized Field "baz"
I understand the API throwing this error; I get it. However, here is a use case for having the API endpoint not throw that error and simply ignore the undefined fields just like the default behavior of the input filter:
Two API endpoints that represent two database tables:
/artists (artists table: id, artists_name)
/albums (albums table: id, artist_id, album_name)
When retrieving an album through /album/:id, you may want to include additional fields in the response via the way of a JOIN:
{
id:1,
artist_id:12,
album:"Best Hits",
artist_name:"Dull Needle & The Statics",
}
It is much more efficient to include the artist's name in the album request instead of making two API calls.
Ok, so what does this GET response have to do with input filters?
We have several apps built using Angular.js since it is great at two way data binding and we can easily push the modified data models up to the server (PATCH, PUT) when the user edits a view. With the current behavior, we would have to clone the data model and filter it in the angular controller, then push it up to the API. In the example above, if you were to leave the model untouched, you would get a 400 response. If a new joined field was added to the response payload you would also have to update the js controller to filter that out for PATCH and PUT operations.
Had the API acted exactly as the InputFilter example, nothing would have to be done on the view layer or in the angular controllers. We could confidently know that extraneous data would be ignored and removed via way of the input filter. We could pass complex relational data via GET and not have to replicate filtering logic in the JS or view side of things for POST, PUT, PATCH.
There should be an option on how to handle this use case. At the very least, it should be up to the developer to decide wether the extra data constitutes an error or not.
Sorry for the length; just tried to explain it clearly.
I configured digest auth and now testing endpoints always throws 403-forbidden.
I set absolute path for htdigest
file in local.php
and I set /my/valid-endpoint
as digest_domain
in global.php
.
This is my curl test (if I disable authentication things run properly):
curl --digest -u "user:pass" -s -H "Accept: application/vnd.myexample.v1+json" http://localhost:8080/my/valid-endpoint
Is Apigility ever going to allow for more complex $resource entries in the ACL? I ask because I'm stumbling upon a limitation when using the default String based Resources..
http://stackoverflow.com/questions/11668785/zend-acl-dynamic-assertion
namely, I want Assertions that check an Entities owner ID and the RoleID either Match.. or are on some sort of authorized table.
I apologize if this belongs in Mvc-Auth project, and if so can move this question to there.
I am running the latest version of Apigility, testing it out. I came across some errors while developing from an IP remote to the local host.
I'm unable to delete DB Adapters nor can I edit API settings.
If this is by design, how can I develop on Vagrant for example with a GUI-less VM?
When I click the red 'Yes' , it thinks I'm clicking the down arrow instead.
This is a weird one. Seems modules with di configs break filters in Apigility. The filters instantiate, but they aren't passed any options. Validators appear to work though. Best to give you the steps to reproduce:
Install a fresh copy of Apigility and vagrant up.
Create a test RPC Service with one field. Apply a filter and some options. I used Alnum, allow white space false.
Edit the RPC controller to simply return the data from the composed input filter.
Post to the API endpoint with some text that contains white spaces. "No White Spaces!!!" You will get the correct, filtered data: "NoWhiteSpaces"
Edit composer.json, adding "webino/webino-image-thumb":"dev-master" to the required-dev and composer update.
Enable the new module, "WebinoImageThumb"
Hit the api endpoint and the data will be filtered, but options ignored: "No White Spaces"
In the newly created modules module.config.php file, comment out all the config and hit the api endpoint again. You will get the correctly filtered data: "NoWhiteSpaces"
Upon inspecting the modules config, I can't see anything that would somehow overwrite a previously set config as it is namespaced. I even tried making the newly installed module the first one to load; same result. I'm not even sure if this is specific to apigility.
Hi,
While creating a input filter validation for email , I have added these validators.
...
1 => array(
'name' => 'email',
'required' => true,
'filters' => array(),
'validators' => array(
0 => array(
'name' => 'Zend\\Validator\\EmailAddress',
'options' => array(
'useDomainCheck' => true,
'useMxCheck' => true,
'useDeepMxCheck' => true,
'message' => 'Email address should be valid and should able to receive email.',
),
),
1 => array(
'name' => 'ZF\\ContentValidation\\Validator\\DbNoRecordExists',
'options' => array(
'adapter' => 'ApiAdapter',
'field' => 'email',
'table' => 'oauth_users',
'message' => 'Email already registered. If you have forgotten the password please use forgot password to retrieve it or use different email address.',
),
),
),
'allow_empty' => false,
'continue_if_empty' => false,
'description' => 'Email of the user.',
'error_message' => 'Email can\'t be empty.',
),
...
The usage of
'useDomainCheck' => true,
'useMxCheck' => true,
'useDeepMxCheck' => true,
makes the validation fail. Resulting in Email can\'t be empty. with 422 error
.
I have checked my environment for getmxrr()
.
$mxHosts = array();
getmxrr('gmail.com', $mxhosts);
var_dump($mxhosts);exit;
The results are
array (size=5)
0 => string 'alt1.gmail-smtp-in.l.google.com' (length=31)
1 => string 'alt3.gmail-smtp-in.l.google.com' (length=31)
2 => string 'alt4.gmail-smtp-in.l.google.com' (length=31)
3 => string 'gmail-smtp-in.l.google.com' (length=26)
4 => string 'alt2.gmail-smtp-in.l.google.com' (length=31)
As I was working with Apigility, I noticed that filters did not get applied.
I went through the code with a collegue, and found that it does get applied on DB-connected resources.
See; https://github.com/zfcampus/zf-apigility/blob/master/src/ZF/Apigility/DbConnectedResource.php#L32
Is this intentional? Wouldn't it be better to have the filters being applied on both code- and DB-connected resources? At least I would expect it, as the validation is done on both code and DB connected resources, but the filters only on DB connected.
I'm having trouble integrating this into an existing zf2 app due to the zf-apigility and the zf-apigility-admin composer.json files containing dependencies that are all set to 'dev-master'.
For example I already depend on: "rwoverdijk/assetmanager": "~1.3" but apigility is requiring dev-master of the same package which is preventing it install.
Also If I try to install both apigility and apigility-admin as "~0.7" then the install fails due to apigility-admin depending on the dev-master version of apigility!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.