-
Notifications
You must be signed in to change notification settings - Fork 281
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
REST API #535
REST API #535
Conversation
@juliushaertl I've managed to reduce the number of errors that were happening with the units tests down to 1. It was pretty simple, phpunit removed setExpectedException and replaced it with a new function. Here's my reference: Roave/BetterReflection#170 The last error is eluding me at the moment, mind giving insights on how to proceed past that error? I'll be starting my own unit tests against the new API real soon :). |
appinfo/routes.php
Outdated
['name' => 'board_api#undo_delete', 'url' => '/api/v1.0/boards/{boardId}/undo_delete', 'verb' => 'POST'], | ||
|
||
['name' => 'stack_api#index', 'url' => '/api/v1.0/boards/{boardId}/stacks', 'verb' => 'GET'], | ||
['name' => 'stack_api#index', 'url' => '/api/v1.0/boards/{boardId}/stacks/{stackId}', 'verb' => 'GET'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't that be handled by stack_api#get
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup! a simple copy/paste oversight!
lib/Controller/Helper/ApiHelper.php
Outdated
|
||
class ApiHelper { | ||
|
||
public static function entityHasError($entityId, $entityName, $service) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can remove the static keyword, since we will always call this on an object due to dependency injection.
|
||
$stack = $this->service->find($this->request->params['stackId']); | ||
|
||
if ($stack == false || $stack == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
=== instead of ==
|
||
$stack = $this->service->delete($this->request->params['stackId']); | ||
|
||
if ($stack == false || $stack == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
=== instead of ==
lib/Controller/Helper/ApiHelper.php
Outdated
return $error; | ||
} | ||
|
||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably better to return an empty array then, so we can have proper return type hints once we have PHP 7.0 as a minimum.
lib/Controller/CardApiController.php
Outdated
return new DataResponse('card id must be a number', HTTP::STATUS_BAD_REQUEST); | ||
} | ||
|
||
$card = $this->cardService->find($this->request->params['cardId']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something more general regarding the service classes. They actually throw various exceptions that come from either the permissionService or the db mappers. Sorry those are not correctly documented in the phpDoc comments. So we need to either add a try/catch block here or extend the service methods to return null in case there is no enity found.
Another approach would be to have a middleware for the API that catches the exceptions and returns a 404 for DoesNotExistException for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which would you prefer? I'm usually all for the try { catch } blocks as it makes the code that much more clear / self documenting, typically avoiding exactly this kind of scenario. I did a test for (false || null) just as a starting point.
All the services are able to throw these exceptions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that makes sense. Let's go that way. Basically they all throw exceptions based on the mapper, but I can push some commit to add proper annotations later, if that helps.
@Nebri I quickly pushed a commit to fix the one failing test. |
Codecov Report
@@ Coverage Diff @@
## master #535 +/- ##
==========================================
- Coverage 79.12% 75.46% -3.66%
==========================================
Files 46 52 +6
Lines 1643 1969 +326
==========================================
+ Hits 1300 1486 +186
- Misses 343 483 +140 |
@Nebri Any another one to add the exception annotations. At some point it would probably be a good idea to catch the database exceptions in the service classes and throw exceptions that better show what exactly went wrong. E.g. for the CardServce::update method we currently have: Would that make sense from your POV? |
Yup That makes perfect sense to me! 👍 |
@juliushaertl Mind taking a look over my commit: ede2144? Getting a bit lost in the weeds on mocking up a unit test that will cause the permissions to fail, and throw the permission exception. Once I figure that out, I'll be able to make a test to ensure the proper DataResponse is generated. I commented out the code segment I'm struggling with, and labelled it as a place of dragons ;) |
Is this true for all the exceptions that could be occuring in the rest api? I've taken a look at SharingMiddleware and I've noticed it's taking exceptions and returning out json responses. if you look at the Board / Stack api controllers I've defined, I'm also trying to build the same json responses using the DataResponse class. Am I essentially creating duplicating code that I don't need to? The rest api code branch so far is almost at 2,000 lines, and based on our discussions this is seeming to get out of hand. Want to make 100% sure I'm not wasting effort re-inventing the wheel here :). |
Yes, at least for the NoPermissionException, which is a StatusException that is catched by the Middleware.
You can get rid of those checks https://github.com/nextcloud/deck/pull/535/files#diff-aa1cba99409af542c6b24c8140e1415bR115 The middleware will automatically return a JSONResponse for any StatusException that is thrown in a controller. We probably should also move the other checks to the services and just throw a StatusException for those as well, but I need to think about that a bit. |
Alright I'm going to pause work on this branch until we have a solid plan of attack for how to handle these exceptions, as it greatly affects the complexity and location of the relevant unit tests. |
@juliushaertl This is ready for another review round. |
lib/BadRequestException.php
Outdated
namespace OCA\Deck; | ||
|
||
use OCP\AppFramework\Http; | ||
class BadRequestException extends \Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extend from StatusException
so we don't need an additional check for that in the Middleware.
lib/Middleware/SharingMiddleware.php
Outdated
@@ -59,7 +60,7 @@ public function __construct(ILogger $logger, IConfig $config) { | |||
* @throws \Exception | |||
*/ | |||
public function afterException($controller, $methodName, \Exception $exception) { | |||
if ($exception instanceof StatusException) { | |||
if ($exception instanceof StatusException || $exception instanceof BadRequestException) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed if BadRequestException is a StatusException.
* Create a new label | ||
*/ | ||
public function create($title, $color) { | ||
$label = $this->labelService->create($title, $color, $this->request->getParam('boardId')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still need some checks as in the other services here as well 😉
@Nebri Looks good from the Service/Controller separation now. Some things we still need endpoints for, or maybe we can adjust the current ones to offer an option for are:
I'd be fine if we obmit the following for the first version of the API:
But it would of course nice to also have those 😉 |
Of course, let's do it right! I have no intention of rushing this. I've been taking job interviews this week, next week is looking clear for the moment. |
@juliushaertl I've just written the attachments api. I'm assuming that we also want to go through the services to put in the BadRequestException across the board? I'd also like to request that we do the acl permissions in a separate issue. I'd like to keep the scope creep in check. Let's fix anything that may still be outstanding here, get it merged, and then build the permissions on top. let me know what you think. |
That would be good yes.
Sure, we can do this later on. Maybe you can just create an issue for that, so we don't forget about it. That will also make it a bit easier to review then. Better have several small steps there 😉 |
Heya, thanks for jumping on this. @Nebri Every time I had planned to work on it, something else came up, and I just got stuck. Really glad to see this moving along! |
Signed-off-by: Ryan Fletcher <[email protected]>
…tests in BoardApiController Signed-off-by: Ryan Fletcher <[email protected]>
…it tests. Signed-off-by: Ryan Fletcher <[email protected]>
Signed-off-by: Ryan Fletcher <[email protected]>
…odacy complexity rules by a lot. Also moved validation checks into respective services. Signed-off-by: Ryan Fletcher <[email protected]>
Signed-off-by: Ryan Fletcher <[email protected]>
Signed-off-by: Ryan Fletcher <[email protected]>
Signed-off-by: Ryan Fletcher <[email protected]>
… extending StatusException Signed-off-by: Ryan Fletcher <[email protected]>
Signed-off-by: Ryan Fletcher <[email protected]>
Signed-off-by: Ryan Fletcher <[email protected]>
…ntApicontroller. Trying out test driven development. Signed-off-by: Ryan Fletcher <[email protected]>
…dService Signed-off-by: Ryan Fletcher <[email protected]>
Signed-off-by: Ryan Fletcher <[email protected]>
Signed-off-by: Ryan Fletcher <[email protected]>
Signed-off-by: Ryan Fletcher <[email protected]>
… DefaultBoardService BadRequestException checks. Signed-off-by: Ryan Fletcher <[email protected]>
Signed-off-by: Ryan Fletcher <[email protected]>
Signed-off-by: Julius Härtl <[email protected]>
Signed-off-by: Julius Härtl <[email protected]>
Signed-off-by: Julius Härtl <[email protected]>
Signed-off-by: Julius Härtl <[email protected]>
Signed-off-by: Julius Härtl <[email protected]>
12b6b7e
to
5639bd1
Compare
The big heavy development work is now done and ready for it's first review round.
I'm planning on writing a series of unit tests against the Api Controllers, and after doing the rebase a bunch of unit tests that were passing are no longer. I'll start taking a look at these units tests later this weekend.
When this PR gets merged it will close Issue #83