How to add custom exception on JSON:API requests? - php

I'm using Drupal 9, JSON:API module, Domain access module.
My task is to throw a custom exception when the request doesn't contain a specific parameter (domain-entity in my case).
For example - test-website.com/domain-parameter/jsonapi/some-entity
I need to throw a text "Please, specify domain-parameter to get correct data" if the domain-parameter is not specified in the URL above.
I've read a lot of articles about handling JSON API requests/altering JSON-API responses etc., but nothing helped me. I've found information that it's possible to achieve by writing a custom EventsSubscriber, but I'm not sure whether it's the best option.
Appreciate any help.

Related

Laravel 5 API request validation

I'm working with Laravel 5 API. I have a few methods with similar request parameters
For example to check the licence status or get the settings file you need to provide the ?serial=licence_serial_number parameter.
I need to return 400 error code, when the user didn't provide the serial parameter, and 403 error code, when the user is trying to get information about the licence of another user.
What is the best practice to organise validation and error handling of these kind of requests?
Should I make a middleware to check if the user has provided ?serial?
Or should I make a different Laravel 5 FormRequest class for every method?
Or should I validate it directly in a controller with:
if (..) {return response()->json([..], 400);}
$request->wantJson(), with a request with Header Accept=application/json Will tell Laravel to return json validation error instead of goback with errors
Middleware will probably be the best choice but you could also use the Request method.Inline validation is a bad practice as its ignore the most basic rule of programming - Dont Repeat Yourself.
In case you decide go for the request option you aren't supposed to create the authorize method for each class,instead create 1 parent witch will handle this and the other sub classes will just have the rules method.
It depends on a few things acctualy:
If your always validating the same thing for all requests: Go With a Middleware Solution.
But if some or multiple requests validate different things then I would advise on using the new FormRequest from Laravel.
It handles the validation for your request perfectly, and also allows you the define the error responses per request.
Also a middleground is an option, Let middleware validate the thing that needs to be validated always. And FormRequests to handle the variable validation.
If you have similar FormRequests, consider using inheritance to prevent code duplication like a good SOLID programmer :-)

Zend_Form and RESTful HTTP request

I have implemented a search form in Zend ( SOLR in the backend ).
To offer the user some more control I have added a multicheckbox for applying certain content filters.
The thing is in the following steps ( bear with me here ):
The request is made, something similar to /search/?q=bla&filter=1
The request is rewritten in the controller to be restful to: /search/query/bla/filter/1
If the user removes filter 1, adds filter 2 and submits the request becomes: /search/query/bla/filter/1?q=bla&filter=2
How would I properly create a restful request using that. The problem being here that using the getRequest() functionality of the Controller I will also get a value for the first filter, meaning I have no way of knowing which one I can discard.
So, to summarize:
How do I properly use a Zend_Form to create RESTful HTTP requests
IMO, you're trying to solve an inexistent problem. You're working on aesthetics not RESTful compliance.
REST tells that you need to identify resources, not that you're resource links should look nice (well in a way). But since your search is a kind of a filter, it is totally acceptable to use a QueryParam.
I think, your use of the term "search" within REST is wrong. Search is not a resource (at least in your case).
You should either hide the search implementation by doing something like:
GET /articles?q=foo&filter=1
The way you construct your filters criteria should not matter.
Or you may want to define a "search" as a resource (SO actually does that IIRC).
POST /articles/search/
"{
"query" : "foo",
"filter" : "bar"
}"
Would result in something like:
Location: /articles/search/a125f41fbc135d
Where a125f41fbc135d is the identifier of the search which would be used to identify the search resource.

What is the best way to to execute code before a page is loaded

Based on my previous question, in Enterprise Edition Magento it doesn't appear to be a good idea to use any of the available controller events if you are planning on having the full page caching enabled. It looks to be you only want to use these events if you are doing something with the actual page.
However, we have built some extensions for Magento that on controller_action_predispatch, we have an observer and from there we grab a parameter in the URL and if it is set correctly we do some additional functionality from there. For example, we have made it so a client can put promo codes in urls for email campaigns and when they click that link it is attached to the customer's quote. We have to look for the parameter before the page is loaded and do our thing.
But now that there is this full page caching it isn't working correctly. So is it probably better to not do this with an Observer and just extend the code? Or are there better Observers to do this with. We tried to use HTTP send response before one and got mixed results.
If you cannot find a suitable event then request one, or create it yourself. Perhaps extending Enterprise_PageCache_Model_Processor and checking to see what it returns, if non-empty then trigger the new event. Then watch both events with a single observer.
If you want to keep your investment in the controller_action_predispatch events and stay in the Magento framework for your code, you could do a couple of things.
Add the URL param into the cache key. That way the FPC will serve the different versions of the page that the param can trigger while still giving the benefit of caching. Refer to this blog post for an example of creating your own PageCache container and overriding the cache key.
Exclude those controllers from FPC. Obviously this is only valid if the controllers affected are a subset of the overall site, otherwise you won't get any caching benefit.
Cheers,
JD
Maybe auto_prepend_file directive could help?

Error handling Symfony custom library

Hey guys, I'm writing a library that will reside in the /lib folder that deals with processing a credit/debit card transaction.
I'm using the Forms framework to accept and validate the card details and then from my actions.class.php for that module, it instantiates my custom library that deals with the SOAP call to process the transaction.
My question is what is the best way to handle the potential errors, ie. setting up the SOAP call, processing the call, and then handling the response, which in terms of the transaction might be success or fail (with more information to feed back?).
I'm thinking something like a global error array and pre-defined error messages set in a config file somewhere. My actions.class.php ultimately receives a TRUE or FALSE, but if FALSE I need to inspect the error array and deal with it accordingly.
Any ideas?
Thank
What is the "place" that knows all about the potential errors? From your description I think it's the SOAP library. If it's your library, you should put the error codes there. Depending on how you show the errors to the user and if/how your app is localized, you then put the actual error messages (= what the user sees) where it makes the most sense.
If the SOAP lib is not yours then inspect the documentation and see what types of errors and error messages you may receive.

Does php mvc framework agavi use CRUD compliant to REST?

The agavi framework uses the PUT request for create and POST for updating information. Usually in REST this is used the other way around (often referring to POST adding information while PUT replacing the whole data record).
If I understand it correctly, the important issue is that PUT must be idempotent, while POST does not have this requirement. Therefore, I wounder how creating a new record can be idempotent (i.e. multiple request do not lead to multiple creations of a record) in particular when usually the ORM uses an id as a primary key and the id of a new record would not be known to the client (since it is autocreated in the database), hence cannot be part of the request. How does agavi maintain the requirement of idempotence in light of this for the PUT request.
Thanks.
PUT can be used both for creation and for updating complete records. POST is usually used for partial updates and related operations as well as for creating a new type of record on the server without specifying a URL for the resource (e.g. POST to /articles/23/comments returns a 201 status and a Location: /articles/23/comments/283136 header). So in your case (with a sequence/autoincrement ID), you would use that approach.
However, HTML (and thus web forms) is different. It only knows GET and POST, not DELETE and PUT. For deletion and updating operations, it overloads the POST method.
That's why Agavi, by default, maps POST to "write" and GET to "read" - it's the most common use case, and "read" and "write" were chosen because they are relatively neutral and also in a way represent the safety aspects of GET vs POST (safety as in "GET can be called without side effects" and blah).
You can change the mapping of verbs for the AgaviWebRequest implementation in factories.xml; refer to the Agavi users mailing list or the IRC channel if you need help with that (or ask away here). A lot of people on the IRC channel are also quite experienced with URL scheme design in case you need more help with making your API pretty.
Instead of thinking of PUT as creating, think of it as "putting". You put a resource at a URI (ie send an entire resource to a URI).
PUT http://example.com/articles/1
If you repeat this (send the same entire resource to the same URI) you get the same result and you haven't changed the resource at that URI, that's what makes it idempotent.
If agavi's implementation of PUT is idempotent then it is implementing PUT correctly. Otherwise it's not.
PUT can be used to create a resource, except that if the resource already exists (or has already been created by a previous PUT) it will just update it. POST should not update resources, however, if this is simple CRUD. Note that the HTTP verbs do not have a defined mapping to certain actions necessarily, since they're useful for a lot more than just CRUD.
Also note that this question has nothing to do with REST - just proper HTTP usage. So please remove the REST tag.
I've had this problem before. This can be solved by changing the factories.xml

Categories