Skip to content

Commit b83c119

Browse files
committed
Added Endpoint Discovery
1 parent f1fd518 commit b83c119

File tree

11 files changed

+101
-483
lines changed

11 files changed

+101
-483
lines changed

doc/getting-started/endpoint.md

Lines changed: 16 additions & 430 deletions
Large diffs are not rendered by default.

src/Controller/ODCFF.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public function get(string $identifier): Response
167167
$formula = $mashupDoc->createElement('Formula');
168168
$formulaContent = $mashupDoc->createCDATASection(sprintf(
169169
'let Source = OData.Feed("%1$s", null, [Implementation="2.0"]), %2$s_table = Source{[Name="%2$s",Signature="table"]}[Data] in %2$s_table',
170-
app(Endpoint::class)->endpoint(),
170+
app()->make(Endpoint::class)->endpoint(),
171171
$resourceId,
172172
));
173173
$formula->appendChild($formulaContent);

src/Controller/PBIDS.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function get(): Response
4444
'details' => [
4545
'protocol' => 'odata',
4646
'address' => [
47-
'url' => app(Endpoint::class)->endpoint(),
47+
'url' => app()->make(Endpoint::class)->endpoint(),
4848
],
4949
],
5050
],

src/Controller/Transaction.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,7 @@ public function getPath(): string
785785
*/
786786
public function getRequestPath(): string
787787
{
788-
$route = app(Endpoint::class)->route();
788+
$route = app()->make(Endpoint::class)->route();
789789
return Str::substr($this->request->path(), strlen($route));
790790
}
791791

@@ -963,7 +963,7 @@ public function getContextUrl(): string
963963
*/
964964
public static function getResourceUrl(): string
965965
{
966-
return app(Endpoint::class)->endpoint();
966+
return app()->make(Endpoint::class)->endpoint();
967967
}
968968

969969
/**

src/Endpoint.php

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,39 @@
22

33
namespace Flat3\Lodata;
44

5-
use Flat3\Lodata\Interfaces\ServiceEndpointInterface;
6-
7-
class Endpoint implements ServiceEndpointInterface
5+
class Endpoint
86
{
7+
/**
8+
* @var string $serviceUri the &lt;service-uri> of the <code>Flat3\Lodata\Model</code>.
9+
*/
910
protected $serviceUri;
1011

12+
/**
13+
* @var string $route the route prefix configured in <code>'lodata.prefix'</code>
14+
*/
1115
protected $route;
1216

17+
/**
18+
* @var string $endpoint the full url to the ODataService endpoint
19+
*/
1320
protected $endpoint;
1421

1522
public function __construct(string $serviceUri)
1623
{
17-
$this->serviceUri = trim($serviceUri, '/');
24+
$this->serviceUri = rtrim($serviceUri, '/');
1825

1926
$prefix = rtrim(config('lodata.prefix'), '/');
20-
21-
$this->route = ('' === $this->serviceUri)
27+
$this->route = ('' === $serviceUri)
2228
? $prefix
2329
: $prefix . '/' . $this->serviceUri;
2430

2531
$this->endpoint = url($this->route) . '/';
2632
}
2733

28-
public function serviceUri(): string
29-
{
30-
return $this->serviceUri;
31-
}
32-
34+
/**
35+
* @return string the path within the odata URI space, like in
36+
* https://<server>:<port>/<config('lodata.prefix')>/<service-uri>/$metadata
37+
*/
3338
public function endpoint(): string
3439
{
3540
return $this->endpoint;
@@ -40,18 +45,13 @@ public function route(): string
4045
return $this->route;
4146
}
4247

43-
public function namespace(): string
44-
{
45-
return config('lodata.namespace');
46-
}
47-
48-
public function cachedMetadataXMLPath(): ?string
49-
{
50-
return null;
51-
}
52-
48+
/**
49+
* Discovers Schema and Annotations of the `$metadata` file for
50+
* the service.
51+
*/
5352
public function discover(Model $model): Model
5453
{
54+
// override this function to register all of your $metadata capabilities
5555
return $model;
5656
}
5757
}

src/Entity.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ public static function pipe(
178178
}
179179

180180
$entityId = $id->getValue();
181-
$endpoint = app(Endpoint::class)->endpoint();
181+
$endpoint = app()->make(Endpoint::class)->endpoint();
182182
if (Str::startsWith($entityId, $endpoint)) {
183183
$entityId = Str::substr($entityId, strlen($endpoint));
184184
}

src/Model.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ public function getTypeDefinition(string $name): ?Type
199199
*/
200200
public static function getNamespace(): string
201201
{
202-
return app(Endpoint::class)->namespace();
202+
return config('lodata.namespace');
203203
}
204204

205205
/**
@@ -344,7 +344,7 @@ public function discover($discoverable): self
344344
*/
345345
public function getEndpoint(): string
346346
{
347-
return app(Endpoint::class)->endpoint();
347+
return app()->make(Endpoint::class)->endpoint();
348348
}
349349

350350
/**

src/PathSegment/Batch/JSON.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function emitJson(Transaction $transaction): void
5959

6060
$requestURI = $requestData['url'];
6161

62-
$endpoint = app(Endpoint::class)->endpoint();
62+
$endpoint = app()->make(Endpoint::class)->endpoint();
6363
switch (true) {
6464
case Str::startsWith($requestURI, '/'):
6565
$uri = Url::http_build_url(

src/PathSegment/OpenAPI.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ public function emitJson(Transaction $transaction): void
409409

410410
$queryObject->tags = [__('lodata::Batch requests')];
411411

412-
$route = app(Endpoint::class)->route();
412+
$route = app()->make(Endpoint::class)->route();
413413

414414
$requestBody = [
415415
'required' => true,

src/ServiceProvider.php

Lines changed: 54 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,14 @@
2121

2222
/**
2323
* Service Provider
24+
*
25+
* https://<server>:<port>/<prefix>/<service-uri>/$metadata
26+
*
2427
* @link https://laravel.com/docs/8.x/providers
2528
* @package Flat3\Lodata
2629
*/
2730
class ServiceProvider extends \Illuminate\Support\ServiceProvider
2831
{
29-
/**
30-
* Get the endpoint of the OData service document
31-
* @return string
32-
*/
33-
public static function endpoint(): string
34-
{
35-
return url(self::route()).'/';
36-
}
37-
38-
/**
39-
* Get the configured route prefix
40-
* @return string
41-
*/
42-
public static function route(): string
43-
{
44-
return rtrim(config('lodata.prefix'), '/');
45-
}
46-
4732
/**
4833
* Service provider registration method
4934
*/
@@ -59,14 +44,61 @@ public function boot()
5944
{
6045
if ($this->app->runningInConsole()) {
6146
$this->publishes([__DIR__.'/../config.php' => config_path('lodata.php')], 'config');
47+
$this->bootServices(new Endpoint(''));
6248
}
49+
else {
50+
// Let’s examine the request path
51+
$segments = explode('/', request()->path());
52+
53+
// we only kick off operation when path prefix is configured in lodata.php
54+
// as all requests share the same root configuration
55+
if ($segments[0] === config('lodata.prefix')) {
56+
57+
// next look up the configured service endpoints
58+
$serviceUris = config('lodata.endpoints', []);
59+
60+
$service = null;
61+
if (0 === sizeof($serviceUris)) {
62+
// when no locators are defined, fallback to global mode; this will
63+
// ensure compatibility with prior versions of this package
64+
$service = new Endpoint('');
65+
}
66+
else if (array_key_exists($segments[1], $serviceUris)) {
67+
$clazz = $serviceUris[$segments[1]];
68+
$service = new $clazz($segments[1]);
69+
}
70+
else {
71+
// when no service definition is configured for the path segment,
72+
// we abort with an error condition; typically a dev working on
73+
// setting up his project
74+
abort('No odata service endpoint defined for path ' . $segments[1]);
75+
}
76+
77+
$this->bootServices($service);
78+
}
79+
}
80+
}
81+
82+
private function bootServices($service): void
83+
{
84+
// register the $service, which is a singleton, with the container; this allows us
85+
// to fulfill all old ServiceProvider::route() and ServiceProvider::endpoint()
86+
// calls with app()->make(ODataService::class)->route() or
87+
// app()->make(ODataService::class)->endpoint()
88+
$this->app->instance(Endpoint::class, $service);
6389

6490
$this->loadJsonTranslationsFrom(__DIR__.'/../lang');
6591

66-
$this->app->singleton(Model::class, function () {
67-
return new Model();
68-
});
92+
// next instantiate and discover the global Model
93+
$model = $service->discover(new Model());
94+
assert($model instanceof Model);
95+
96+
// and register it with the container
97+
$this->app->instance(Model::class, $model);
6998

99+
// I don't get why you are doing this twice? You never load the model
100+
// via app()->make('lodata.model') or app()->make(Model::class). What
101+
// am I missing here?
70102
$this->app->bind('lodata.model', function ($app) {
71103
return $app->make(Model::class);
72104
});
@@ -83,7 +115,7 @@ public function boot()
83115
return version_compare(InstalledVersions::getVersion('doctrine/dbal'), '4.0.0', '>=') ? new DBAL\DBAL4($args['connection']) : new DBAL\DBAL3($args['connection']);
84116
});
85117

86-
$route = self::route();
118+
$route = $service->route();
87119
$middleware = config('lodata.middleware', []);
88120

89121
Route::get("{$route}/_lodata/odata.pbids", [PBIDS::class, 'get']);

0 commit comments

Comments
 (0)