diff --git a/docs/06-concepts/01-working-with-endpoints/02-endpoint-inheritance.md b/docs/06-concepts/01-working-with-endpoints/02-endpoint-inheritance.md index fe19d616..1e406d1d 100644 --- a/docs/06-concepts/01-working-with-endpoints/02-endpoint-inheritance.md +++ b/docs/06-concepts/01-working-with-endpoints/02-endpoint-inheritance.md @@ -108,12 +108,34 @@ This way, you can modify the behavior of endpoint methods while still sharing th ## Hiding endpoint methods with `@doNotGenerate` -In case you want to hide methods from an endpoint use `@doNotGenerate` in the child class like so: +In case you want to hide a method that the child class declares itself (i.e. one that is not inherited from a parent class whose client is still being generated), annotate it with `@doNotGenerate` like so: ```dart import 'package:serverpod/serverpod.dart'; -abstract class CalculatorEndpoint extends Endpoint { +class AdderEndpoint extends Endpoint { + Future add(Session session, int a, int b) async { + return a + b; + } + + @doNotGenerate + Future subtract(Session session, int a, int b) async { + throw UnimplementedError(); + } +} +``` + +`AdderEndpoint` exposes `add`, but `subtract` is annotated with `@doNotGenerate` and is therefore excluded from the generated client. + +### Hiding an inherited method + +Hiding a method that is *inherited* from a parent class only works if the parent class itself is fully annotated with `@doNotGenerate`, meaning no client class is generated for it at all: + +```dart +import 'package:serverpod/serverpod.dart'; + +@doNotGenerate +class CalculatorEndpoint extends Endpoint { Future add(Session session, int a, int b) async { return a + b; } @@ -125,16 +147,21 @@ abstract class CalculatorEndpoint extends Endpoint { class AdderEndpoint extends CalculatorEndpoint { @doNotGenerate + @override Future subtract(Session session, int a, int b) async { throw UnimplementedError(); } } ``` -Since `CalculatorEndpoint` is `abstract`, it will not be exposed on the server. `AdderEndpoint` inherits all methods from its parent class, but since it opts to hide `subtract` by annotating it with `@doNotGenerate` only the `add` method will be exposed. +Since `CalculatorEndpoint` is annotated with `@doNotGenerate`, it will not be exposed on the server, and no client class is generated for it. `AdderEndpoint` inlines the inherited methods directly, and since it re-declares `subtract` with `@doNotGenerate`, only `add` is exposed on the generated client. Don't worry about the exception in the `subtract` implementation. That is only added to satisfy the Dart compiler – in practice, nothing will ever call this method on `AdderEndpoint`. -Hiding endpoints from a super class is only appropriate in case the parent `class` is `abstract` or annotated with `@doNotGenerate`. Otherwise, the method that should be hidden on the child would still be accessible via the parent class. +:::warning +If the parent class is only `abstract` (and not itself annotated with `@doNotGenerate`), Serverpod still generates an abstract client class that mirrors it, and every subclass's generated client must implement all of its methods. In that case, `@doNotGenerate` **cannot** be used to hide an inherited method – doing so removes the method from the subclass's generated client while the abstract client class still declares it, which causes a Dart compile error ("missing concrete implementation"). To hide an inherited method, the parent class must be marked `@doNotGenerate` itself, not just `abstract`. + +If the parent class is a normal, concrete class (neither `abstract` nor `@doNotGenerate`), it is exposed on the server and the client in its own right. Hiding the method on the child only removes it from the child's client – it remains accessible through the parent's own generated client class. +::: ## Unhiding endpoint methods annotated with `@doNotGenerate` in the super class