TYPO3, Extbase and use web services instead of database - typo3

Supposed you need to interact with/integrate 5+ different web service sources instead of tables from the database.
In first lane each WS supports read methods like search,list and single view (in short, no CUD from CRUD). Write access should also take place later.
What would be your approach to integrate those to extbase?
I'd like to stick to the conventions of models and repositories. In this case, i think we need to use Models and CustomRepositories. Should the repositories interact directly with the webservice or should we think bigger with an PersistenceManagerInterface implementation and extending the Generic/Query to e.g. paginate on the results by extbase conventions? What is about TypeConverters and PropertyMappers for linking between controller actions with the models "as parameters".
How could a mapping from JSON to the models look like? A TCA configuration is required for the DataMapper, but this is not available because no DB is used, so it cannot be used.
Where should you start?

Related

Why doesn't TYPO3 have a Page Model in Core?

When I use the core PageRepository (TYPO3\CMS\Frontend\Page\PageRepository), function getPage(), I get an array returned and not an object, as in many other core repositories.
Then I have to build some "magic" for myself in order to inject the Categories or the Page Author as Objects to be used in the Fluid Templates.
Question is if it is a kind of "design decision" not to provide a Page Model at all?
You would not have to build an object out of the array for usage in Fluid.
You can also just pass the array to the view. You would use the .-notation just like with an object.
E.g. in the controller:
$this->view->assign('page', $page);
Fluid:
{page.title}
It wouldn't make much sense to ship a Extbase Page domain model for various reasons:
TYPO3 itself wouldn't need it.
The model would need to be extremely generic since it cannot know anything about your domain requirements.
Due to this the model would be too generic for basically any domain requirement which in turn would require you to add your own Page domain model anyways.
And yes, the same applies to the shipped FrontendUser and related classes and these have been deprecated with TYPO3v11 and will be dropped with TYPO3v12.
The PageRepository is not used in Extbase context, so there is no Domain modelling here, because it also is used a lot in backend context and on very low level core execution, where Extbase is not available or it would be to much overhead to boot up Extbase.
You can simply map the pages table on to a model of yourself and use proper Domain modelling this way, when using Extbase in your extension. The core does not provide an Extbase Domain model for pages, afaik.

Create ABAP REST Class to query multiple entities

I don't have Gateway available in my landscape and I want to use the ABAP REST library to expose web services: SAP Library - REST Programming Tutorial
With a very simple example, I successfully created a class to read a single domain list of values, the GET call is quite simple:
http://mydomain/domainvalues/XFELD
And the GET implementation is in my class ZCL_REST_DOMAIN_VALUES extending from CL_REST_RESOURCE implementing IF_REST_RESOURCE~GET method.
Now I want to make it possible to read or query multiple domains. I'm not an expert in REST but I've seen two options searching around, one using the same URI as the single entity and one with special URI for queries.
http://mydomain/domainvalues?Id=XFELD,WERKS_D
http://mydomain/query/domainvalues?Id=XFELD,WERKS_D
In the backend, should I use the second approach and create a class only for this call named for instance ZCL_REST_DOMAIN_VALUES_QUERY implementing the GET method again?
Or maybe should I use POST method to send the list of IDs to fetch in the body?
SAP's own in-house guidelines recommend to shape OData and plain REST services alike, to avoid confusion and facilitate switching between the two:
http://mydomain/domainvalues?$filter=Id in ('XFELD', 'WERKS_D')
Both would be served by the same REST endpoint handler class, although of course you are free to create separate methods or delegates for the cases.
Remember to sanitize (= whitelist/blacklist/escape) the query parameters before handing them over to some lower level to prevent SQL injection attacks, as #SandraRossi correctly pointed out below.

CQRS Project Structure

I have been using the following project structure in projects for some time, but want to start using CQRS/Event Sourcing. Looking for suggestions of how to structure the projects.
Currently I use this:
ProjectName.Common: Extension methods, helpers, etc.
ProjectName.Core: Contains the Domain Model and Service Interfaces that define how to interact with the Domain Model. I have been using Anemic Domain Models, but am looking to move to richer DDD models.
ProjectName.Data: Contains the Repositories and UnitOfWork used to persist Domain Models to Entity Framework.
ProjectName.Services: Conatins all of the Service Implementations described in the ProjectName.Core.Services namespace. Also contains the core business logic and validation and coordinates the retrieving and saving of Domain Models to the database via the repositories and unit of work.
ProjectName.Web: Usually an ASP.NET MVC project or some other Presentation Layer.
What would the same thing in a CQRS/Event Sourcing pattern look like as far as structure goes?
I have read this post here: CQRS/Event sourcing project structure, but was looking for other ideas and examples.
If there is a need for the application to scale, make sure you are able to separate (if/when necessary) command handlers and event denormalizers into multiple projects. In extreme cases it could be 1 command/event handler per project.
It also means that commands and events would need to be in separate projects so they could be distributed among command and event handlers. Typically, command handlers would need to be able the domain project and the event store project. Events denormalizers would need to access the read model data access project.
UX, infrastructure, unit tests can be structured in any way that works for you.

CRUD with external REST service as Model in Loopback

A couple quick questions:
I would like to use an external REST API service (e.g. AgileCRM). With their service, I would like to use the REST Connector within a model that allows me to CRUD AgileCRM's API. Is this possible? If so, what model should be the base (e.g. PersistedModel, Model, etc)?
I would like to merge data from AgileCRM and a PersistedModel (e.g. MySQL). Should I do this via relationships OR inheritance? If inheritance, which should be the parent model? It would be ideal to use all data from AgileCRM (represented as a model in LB, if possible) and add information from a local MySQL database.
Have you any thoughts on wrapping an API service (e.g. AgileCRM) as a connector type (e.g. REST Connector for AgileCRM, based on REST Connector)? AgileCRM has many features but their CRUD methods operate slightly different from how LB interacts with data sources.
This is a really old question, sorry it never got answered, but it's also very broad is some portions. I would recommend asking shorter, more specific questions, and making multiple StackOverflow questions for them.
That said, here's some brief answers for people reading this entry:
Yes, this is possible. Check out the REST connector.
I would probably use multiple parent models that are internal and then a single exposed REST model (not "persisted") that collates that data together.
Sure, you could do that. Writing a connector isn't too difficult, check out our docs on building a connector.

How can I setup OData and EF with out coupling to my database structure?

I really like OData (WCF Data Services). In past projects I have coded up so many Web-Services just to allow different ways to read my data.
OData gives great flexibility for the clients to have the data as they need it.
However, in a discussion today, a co-worker pointed out that how we are doing OData is little more than giving the client application a connection to the database.
Here is how we are setting up our WCF Data Service (Note: this is the traditional way)
Create an Entity Framework (E)F Data Model of our database
Publish that model with WCF Data Services
Add Security to the OData feed
(This is where it is better than a direct connection to the SQL Server)
My co-worker (correctly) pointed out that all our clients will be coupled to the database now. (If a table or column is refactored then the clients will have to change too)
EF offers a bit of flexibility on how your data is presented and could be used to hide some minor database changes that don't affect the client apps. But I have found it to be quite limited. (See this post for an example) I have found that the POCO templates (while nice for allowing separation of the model and the entities) also does not offer very much flexibility.
So, the question: What do I tell my co-worker? How do I setup my WCF Data Services so they are using business oriented contracts (like they would be if every read operation used a standard WCF Soap based service)?
Just to be clear, let me ask this a different way. How can I decouple EF from WCF Data Services. I am fine to make up my own contracts and use AutoMapper to convert between them. But I would like to not go directly from EF to OData.
NOTE: I still want to use EF as my ORM. Rolling my own ORM is not really a solution...
If you use your custom classes instead of using classes generated directly by EF you will also change a provide for WCF Data Services. It means you will no more pass EF context as generic parameter to DataService base class. This will be OK if you have read only services but once you expect any data modifications from clients you will have a lot of work to do.
Data services based on EF context supports data modifications. All other data services use reflection provider which is read only by default until you implement IUpdatable on your custom "service context class".
Data services are technology for creating quickly services exposing your data. They are coupled with their context and it is responsibility of the context to provide abstraction. If you want to make quick and easy services you are dependent on features supported by EF mapping. You can make some abstractions in EDMX, you can make projections (DefiningQuery, QueryView) etc. but all these features have some limitations (for example projections are readonly unless you use stored procedures for modifications).
Data services are not the same as providing connection to database. There is one very big difference - connection to database will ensure only access and execution permissions but it will not ensure data security. WCF Data Services offer data security because you can create interceptors which will add filters to queries to retrieve only data the user is allowed to see or check if he is allowed to modify the data. That is the difference you can tell your colleague.
In case of abstraction - do you want a quick easy solution or not? You can inject abstraction layer between service and ORM but you need to implement mentioned method and you have to test it.
Most simple approach:
DO NOT PUBLISH YOUR TABLES ;)
Make a separate schema
Add views to this
Put those views to EF and publish them.
The views are decoupled from the tables and thus can be simplified and refactored separately.
Standard approach, also for reporting.
Apart from achieving more granular data authorisation (based of certain field values etc) OData also allows your data to be accessible via open standards like JSON/Xml over Http using OAuth. This is very useful for the web/mobile applications. Now you could create a web service to expose your data but that will warrant a change every time your client needs change in the data requirements (e.g. extra fields needed) whereas OData allows this via OData queries. In a big enterprise this is also useful for designing security at infrastructure level as it will only allow the text based (http) calls which can be inspected/verified for security threats via network firewalls'.
You have some other options for your OData client. Have a look at Simple.OData.Client, described in this article: http://www.codeproject.com/Articles/686240/reasons-to-consume-OData-feeds-using-Simple-ODa
And in case you are familiar with Simple.Data microORM, there is an OData adapter for it:
https://github.com/simplefx/Simple.OData/wiki
UPDATE. My recommendations go for client choice while your question is about setting up your server side. Then of course they are not what you are asking. I will leave however my answer so you aware of client alternatives.