Skip to content

Commit

Permalink
chore: aligning view store sample
Browse files Browse the repository at this point in the history
  • Loading branch information
aludwiko committed Dec 27, 2024
1 parent 16da721 commit 7d6178a
Show file tree
Hide file tree
Showing 28 changed files with 223 additions and 115 deletions.
20 changes: 0 additions & 20 deletions docs/src/modules/java/pages/key-value-entities.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -161,23 +161,3 @@ include::example$key-value-counter/src/test/java/com/example/CounterIntegrationT
<5> Explicitly request current value of `bar`. It should be `1`.

NOTE: The integration tests in samples can be run using `mvn integration-test`.

== Exposing entities directly

include::partial$component-endpoint.adoc[]

=== API

The entity is exposed at a fixed path:

[source]
----
/akka/v1.0/entity/<component id>/<entity id>/<method>
----

In our counter example that is:

[source,shell]
----
curl localhost:9000/akka/v1.0/entity/counter/foo/get
----
23 changes: 0 additions & 23 deletions docs/src/modules/java/pages/views.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -318,26 +318,3 @@ include::example$key-value-customer-registry/src/test/java/customer/application/
Views are not replicated directly in the same way as for example xref:event-sourced-entities.adoc#_replication[Event Sourced Entity replication]. A View is built from entities in the same service, or another service, in the same region. The entities will replicate all events across regions and identical Views are built in each region.
A View can also be built from a message broker topic, and that could be regional or global depending on how the message broker is configured.
== Exposing views directly
include::partial$component-endpoint.adoc[]
=== API
The view is exposed at a fixed path:
[source]
----
/akka/v1.0/view/<component id>/<method>
----
Taking the sample from the <<value-entity, first section>> as an example, that would be:
[source,shell]
----
curl localhost:9000/akka/v1.0/view/view_customers_by_email/getCustomer \
--header "Content-Type: application/json" \
-XPOST \
--data '{"email":"[email protected]"}'
----
33 changes: 12 additions & 21 deletions samples/view-store/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ With your Akka service running, once you have defined endpoints they should be a
Create some products:

```shell
curl localhost:9000/akka/v1.0/entity/product/P123/create \
curl -i localhost:9000/products/P123 \
-XPOST \
--header "Content-Type: application/json" \
--data '{
Expand All @@ -31,7 +31,7 @@ curl localhost:9000/akka/v1.0/entity/product/P123/create \
```

```shell
curl localhost:9000/akka/v1.0/entity/product/P987/create \
curl -i localhost:9000/products/P987 \
-XPOST \
--header "Content-Type: application/json" \
--data '{
Expand All @@ -43,13 +43,13 @@ curl localhost:9000/akka/v1.0/entity/product/P987/create \
Retrieve a product by id:

```shell
curl localhost:9000/akka/v1.0/entity/product/P123/get
curl localhost:9000/products/P123
```

Create a customer:

```shell
curl localhost:9000/akka/v1.0/entity/customer/C001/create \
curl -i localhost:9000/customers/C001 \
-XPOST \
--header "Content-Type: application/json" \
--data '{
Expand All @@ -62,13 +62,13 @@ curl localhost:9000/akka/v1.0/entity/customer/C001/create \
Retrieve a customer by id:

```shell
curl localhost:9000/akka/v1.0/entity/customer/C001/get
curl localhost:9000/customers/C001
```

Create customer orders for the products:

```shell
curl localhost:9000/akka/v1.0/entity/order/O1234/create \
curl -i localhost:9000/orders/O1234 \
-XPOST \
--header "Content-Type: application/json" \
--data '{
Expand All @@ -79,7 +79,7 @@ curl localhost:9000/akka/v1.0/entity/order/O1234/create \
```

```shell
curl localhost:9000/akka/v1.0/entity/order/O5678/create \
curl -i localhost:9000/orders/O5678 \
-XPOST \
--header "Content-Type: application/json" \
--data '{
Expand All @@ -92,38 +92,29 @@ curl localhost:9000/akka/v1.0/entity/order/O5678/create \
Retrieve orders by id:

```shell
curl localhost:9000/akka/v1.0/entity/order/O1234/get
curl localhost:9000/orders/O1234
```

```shell
curl localhost:9000/akka/v1.0/entity/order/O5678/get
curl localhost:9000/orders/O5678
```

Retrieve all product orders for a customer id using a view (with joins):

```shell
curl localhost:9000/akka/v1.0/view/joined-customer-orders/get \
--header "Content-Type: application/json" \
-XPOST \
--data '{ "customerId": "C001" }'
curl localhost:9000/orders/joined-by-customer/C001
```

Retrieve all product orders for a customer id using a view (with joins and nested projection):

```shell
curl localhost:9000/akka/v1.0/view/nested-customer-orders/get \
--header "Content-Type: application/json" \
-XPOST \
--data '{ "customerId": "C001" }'
curl localhost:9000/orders/nested-by-customer/C001
```

Retrieve all product orders for a customer id using a view (with joins and structured projection):

```shell
curl localhost:9000/akka/v1.0/view/structured-customer-orders/get \
--header "Content-Type: application/json" \
-XPOST \
--data '{ "customerId": "C001" }'
curl localhost:9000/orders/structured-by-customer/C001
```

## Deploying
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package store.customer.api;

import akka.http.javadsl.model.HttpResponse;
import akka.javasdk.annotations.Acl;
import akka.javasdk.annotations.http.Get;
import akka.javasdk.annotations.http.HttpEndpoint;
import akka.javasdk.annotations.http.Post;
import akka.javasdk.client.ComponentClient;
import store.customer.application.CustomerEntity;
import store.customer.domain.Customer;

import java.util.concurrent.CompletionStage;

import static akka.javasdk.http.HttpResponses.created;

@HttpEndpoint("/customers")
@Acl(allow = @Acl.Matcher(principal = Acl.Principal.INTERNET))
public class CustomerEndpoint {

private final ComponentClient componentClient;

public CustomerEndpoint(ComponentClient componentClient) {
this.componentClient = componentClient;
}

@Post("/{customerId}")
public CompletionStage<HttpResponse> create(String customerId, Customer customer) {
return componentClient.forEventSourcedEntity(customerId)
.method(CustomerEntity::create)
.invokeAsync(customer)
.thenApply(__ -> created());
}

@Get("/{customerId}")
public CompletionStage<Customer> get(String customerId) {
return componentClient.forEventSourcedEntity(customerId)
.method(CustomerEntity::get)
.invokeAsync();
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package store.customer.api;
package store.customer.application;

import akka.Done;
import akka.javasdk.annotations.ComponentId;
import akka.javasdk.eventsourcedentity.EventSourcedEntity;
import store.customer.domain.Address;
import store.customer.domain.Customer;
import store.customer.domain.CustomerEvent;

import static akka.Done.done;
import static store.customer.domain.CustomerEvent.CustomerAddressChanged;
import static store.customer.domain.CustomerEvent.CustomerCreated;
import static store.customer.domain.CustomerEvent.CustomerNameChanged;
Expand All @@ -17,22 +19,20 @@ public ReadOnlyEffect<Customer> get() {
return effects().reply(currentState());
}

public Effect<String> create(Customer customer) {
public Effect<Done> create(Customer customer) {
return effects()
.persist(new CustomerCreated(customer.email(), customer.name(), customer.address()))
.thenReply(__ -> "OK");
.thenReply(__ -> done());
}

public Effect<String> changeName(String newName) {
return effects().persist(new CustomerNameChanged(newName)).thenReply(__ -> "OK");
public Effect<Done> changeName(String newName) {
return effects().persist(new CustomerNameChanged(newName)).thenReply(__ -> done());
}


public Effect<String> changeAddress(Address newAddress) {
return effects().persist(new CustomerAddressChanged(newAddress)).thenReply(__ -> "OK");
public Effect<Done> changeAddress(Address newAddress) {
return effects().persist(new CustomerAddressChanged(newAddress)).thenReply(__ -> done());
}


@Override
public Customer applyEvent(CustomerEvent event) {
return switch (event) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package store.order.api;

import akka.http.javadsl.model.HttpResponse;
import akka.javasdk.annotations.Acl;
import akka.javasdk.annotations.http.Get;
import akka.javasdk.annotations.http.HttpEndpoint;
import akka.javasdk.annotations.http.Post;
import akka.javasdk.client.ComponentClient;
import store.order.application.CreateOrder;
import store.order.application.OrderEntity;
import store.order.domain.Order;
import store.order.view.joined.JoinedCustomerOrdersView;
import store.order.view.nested.CustomerOrders;
import store.order.view.nested.NestedCustomerOrdersView;
import store.order.view.structured.StructuredCustomerOrdersView;

import java.util.concurrent.CompletionStage;

import static akka.javasdk.http.HttpResponses.created;

@HttpEndpoint("/orders")
@Acl(allow = @Acl.Matcher(principal = Acl.Principal.INTERNET))
public class OrderEndpoint {

private final ComponentClient componentClient;

public OrderEndpoint(ComponentClient componentClient) {
this.componentClient = componentClient;
}

@Post("/{orderId}")
public CompletionStage<HttpResponse> create(String orderId, CreateOrder createOrder) {
return componentClient.forKeyValueEntity(orderId)
.method(OrderEntity::create)
.invokeAsync(createOrder)
.thenApply(__ -> created());
}

@Get("/{orderId}")
public CompletionStage<Order> get(String orderId) {
return componentClient.forKeyValueEntity(orderId)
.method(OrderEntity::get)
.invokeAsync();
}

@Get("/joined-by-customer/{customerId}")
public CompletionStage<JoinedCustomerOrdersView.CustomerOrders> joinedByCustomer(String customerId) {
return componentClient.forView()
.method(JoinedCustomerOrdersView::get)
.invokeAsync(customerId);
}

@Get("/nested-by-customer/{customerId}")
public CompletionStage<CustomerOrders> nestedByCustomer(String customerId) {
return componentClient.forView()
.method(NestedCustomerOrdersView::get)
.invokeAsync(customerId);
}

@Get("/structured-by-customer/{customerId}")
public CompletionStage<store.order.view.structured.CustomerOrders> structuredByCustomer(String customerId) {
return componentClient.forView()
.method(StructuredCustomerOrdersView::get)
.invokeAsync(customerId);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package store.order.api;
package store.order.application;

public record CreateOrder(String productId, String customerId, int quantity) {
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
package store.order.api;
package store.order.application;

import akka.Done;
import akka.javasdk.annotations.ComponentId;
import akka.javasdk.keyvalueentity.KeyValueEntity;
import store.order.domain.Order;

import java.time.Instant;

import static akka.Done.done;

@ComponentId("order")
public class OrderEntity extends KeyValueEntity<Order> {

public Effect<Order> get() {
return effects().reply(currentState());
}

public Effect<String> create(CreateOrder createOrder) {
public Effect<Done> create(CreateOrder createOrder) {
Order order =
new Order(
commandContext().entityId(),
createOrder.productId(),
createOrder.customerId(),
createOrder.quantity(),
Instant.now().toEpochMilli());
return effects().updateState(order).thenReply("OK");
return effects().updateState(order).thenReply(done());
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package store.view.joined;
package store.order.view.joined;

import store.customer.domain.Address;
import store.product.domain.Money;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
package store.view.joined;
package store.order.view.joined;

import akka.javasdk.annotations.Query;
import akka.javasdk.annotations.Consume;
import akka.javasdk.annotations.Table;
import akka.javasdk.annotations.ComponentId;
import akka.javasdk.view.View;
import akka.javasdk.view.TableUpdater;
import store.customer.api.CustomerEntity;
import store.customer.application.CustomerEntity;
import store.customer.domain.CustomerEvent;
import store.order.api.OrderEntity;
import store.order.application.OrderEntity;
import store.order.domain.Order;
import store.product.api.ProductEntity;
import store.product.application.ProductEntity;
import store.product.domain.ProductEvent;
import store.view.model.Customer;
import store.view.model.Product;
import store.order.view.model.Customer;
import store.order.view.model.Product;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package store.view.model;
package store.order.view.model;

import store.customer.domain.Address;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package store.view.model;
package store.order.view.model;

import store.product.domain.Money;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package store.view.nested;
package store.order.view.nested;

import store.product.domain.Money;

Expand Down
Loading

0 comments on commit 7d6178a

Please sign in to comment.