I would like to export a stock item from an Acumatica instance as a data contract, but without calling an API. I don't want to call an API, because I need to retrieve it from inside an instance, not external to the instance. I think all I really need is a way to call the contract-based code to serialize into JSON, but without using a URL. I guess I could call the API within the same instance, but it seems like it should be easier than that.
Strictly speaking you want to make API calls. Specifically using the 'contract-based API' without using the 'web services API'. This seems to go against the design goals of the contract-based API.
Consider the following statement:
Contract-based APIs are built on an object model that the web services API provides.
Source:
https://adn.acumatica.com/blog/yes-we-have-an-api-for-that-an-introduction-to-the-acumatica-cloud-erp-apis/
The web service API provides the object model of the contract-based API. Remove the web services API of the equation and the contract based API is missing the object model it is dependent on for object serialization. Practically this means that methods that deal with contract-based serialization will require the web service object model as input parameter.
I believe there would be several technical hurdles preventing instantiation of the web service object model without using the TCP-IP stack. This is mainly because the original design goal of the contract-based API is to be called through web services.
This boils down to Acumatica using different object models for different contexts. Contract-based uses the 'entity' model while customizations use the 'DAC' model. There's also major difference in the querying API. Customizations uses BQL and contract-based have other methods.
There are obvious advantages in having a unified object model. Learning to use only one is easier than having to learn two. Using exclusively JSON is easier than mix and convert XML and JSON. However each model also have their disadvantage. Having different models allows the use of a model better tailored to the task at hand. Common requirements for object models are performance, human readability, memory footprint, ability to be easily machine parsed etc..
That said if all you need is the object model of contract-based API without the querying interface you could approximate it by using BQL and serializing the DAC objects to JSON. Because almost all DAC objects have the C# Serializable attribute it should be much easier to serialize the DAC objects retrieved with BQL than use data-contract API to retrieve and serialize the records without going through TCP-IP stack. It would also go in the same direction of the design goals of the API which is that the contract-based API should be used for access through webservice.
Related
I have a two-layer application which has the bottom layer for collecting data from external APIs and adding it to database and the second layer is for return data from database that is based on the data that I collected from the external API calls.
so I managed to put the external API calls in the infrastructure repositories with their interface in the domain.
So generally where I'm exactly stuck is to save this data that I'm collecting in database without creating a model for this data in the domain since this data is dependable on the external API I want to have this two layers totally separated collecting the data and return the other data without breaking the principles of domain-driven-design.
What I will try to answer here is how DDD could help and highlight that the import is an implementation detail after you applied some DDD principle to find a useful design and an appropriated implementation.
So you need data for your App/Bounded context which will have to generate statistics (if you can put more business language here DDD will be even more helpful). What is the business use of this app ? what are the languages (Ubiquitous Language) and boundaries (BC) ? How is it going to interop with others contexts (Context Mapping).
You will need implement this model, and here you could use the concepts defined and define a persistence model (potentially the language used in the API isn't the language used by your app) and also you might need some validations and business rules during the import of the data. Because you might define Aggregates that ensure the integrity of the system, well here I am speculating. But this is a scenario how I would applied DDD and to make the point that we cannot apply DDD to import. But import is potentially an implementation detail.
So, I've got a WCF service that accepts commands and maps them to calls into the domain services layer. When doing write type of commands to the domain, this pattern is nearly perfect.
What I'm wondering is how everyone is doing reads, more specifically, getting lists of aggregates from the model for display. As I stated, I have a WCF service that calls into the service layer. Currently, I have a method on my service that returns a list of aggregate roots. Somehow, this feels a bit dirty. I'm polluting my domain services with GetByXXXX kind of methods.
I'm looking for a bit of guidance on the search and retrieval of domain objects through the application services layer.
Edit:
Thinking and reading a bit more, is it appropriate to directly use a repository in the application layer to handle fetching of entities?
I usually go with a simple query layer that returns a DataTable for collections and a DataRow for 1 item. For something more structured I would use a DTO. So all your GetByXXX methods could sit in the query layer.
Repositories are better suited for supporting operations that change state. Even when you're fetching an aggregate through a Repository, it is because you intend to change the state and persist it back right away:
var entity = repository.Get(id);
entity.ChangeSomeState();
repository.Save(entity);
In that scenario, Get returns an aggregate that is ready for modification (e.g. attached to the context if using EF, or session in NHibernate). The focus here is consistency.
Now, for queries you are better off with a Query class, which will support read-only scenarios and with a focus on performance.
All your GetByXXX will live in the Query class. You can even create specialized Query classes, e.g. one for Admin queries, another for Customer queries, and so on.
For extra info, have a look at these articles:
Command and Query Responsibility Segregation (CQRS) pattern
CQRS with MediatR in ASP.NET Core 3.1 – Ultimate Guide
I am looking at Couch Db and I saw Ektorp that presents a JPA like interface for database. However I see that there are examples that how to make query at JavaScript. I didn't understand how the system work.
Do I query a database from web tier without a middle tier? How can security be done with that?
CouchDB uses javascript to define map and reduce functions for it's views. Ektorp is simply providing you a convenient way to create those functions that will be used by couchdb. You might want to read the couchdb wiki page on views:
http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views
Just because the views are javascript, does not imply that you have to create the views from a 'web tier'.
In terms of architecture, you have a couple of options. You can use a traditional three tier approach with a java front end, and in your middle tier call couchdb with ektorp. Then you are in full control of security.
You can also go with what is coming to be known as the 2.1 tier model, where users interact directly with couchdb, mainly with a couchapp. You can then provide support services that listen to the changes feed. I have done this with ektorp and it works very well. Other have used node.js. It is a different way of thinking, but it can work. You can read a fun post about this model here:
http://markmail.org/thread/cfw7f3ef75aoqzin
Anyway, I just wanted to provide you with possible options in how you 'tier' your architecture.
Without getting into all of the gory details, I am trying to design a service-based solution that will be consumed by several client applications. The solution allows admins to create and modify document templates which are used by regular users to perform data entry. It is my intent to make the application a learning tool for best practices, techniques, etc.
And, at the same time, I have to accomodate a schizophrenic environment because the 'powers that be' cannot ever stick to their decisions regarding technologies and tools. For example, I am using Linq-to-SQL today because they aren't ready to go to EF4 but there is also discussion about switching over to NHibernate. So, I have to make the code as persistent ignorant as possible to minimize the work required should we change OR/M tools.
At this point, I am also limited to using the partial class approach to extend the Linq-to-SQL classes so they implement interfaces defined in my business layer. I cannot go with POCOs because management insists that we leverage all built-in tooling, etc. so I must support the Linq-to-SQL designer.
That said, my service interface has a StartSession method that accepts a template identifier in its signature. The operation flows like this:
If a session already exists in the database for the current user and specified template, update the record to show the current activity. If not, create a new session object.
The session is associated with an instance of the template, call it the "form". So if the session is new, I need to retrieve the template information to create the new "form", associate it with the session then save the session to the database. On the other hand, if the session already existed, then I need to also load the "form" with the data entered by the user and stored in the session previously.
Finally, the session (with form definition and data) is returned to the caller.
My first objective is to create clean separation between the logical layers of my application. The second is to maintain persistence ignorance (as mentioned above). Third, I have to be able to test everything so all dependencies must be externalized for easy mocking. I am using Unity as an IoC tool to help in this area.
To accomplish this, I have defined my service class and data contracts as needed to support the service interface. The service class will have a dependency injected from the business layer that actually performs the work. And here's where it has gotten messy for me.
I've been try to go the Unit of Work and Repository route to help with persistance ignorance. I have an ITemplateRepository and an ISessionRepository which I can access from my IUnitOfWork implementation. The service class gets an instance of my SessionManager class (in my BLL) injected. The SessionManager receives the IUnitOfWork implementation through constructor injection and will delegate all persistence to the UoW but I find myself playing a shell game with the various logic.
Should all of the logic described above be in the SessionManager class or perhaps the UoW implementation? I want as little logic as possible in the repository implementations because changing the data access platform could result in unwanted changes to the application logic. Since my repository is working against an interface, how do I best go about creating the new session (keeping in mind that a valid session has a reference to the template, er, form being used)? Would it be better to still use POCOs even though I have to support the designer and use a tool like AutoMapper inside the repository implementation to handle translating the objects?
Ugh!
I know I am just stuck in analysis paralysis so a little nudge is probably all I need. What would be ideal would be if someone could provide an example how you would you would solve the problem given the business rules and architectural constraints I've defined.
If you don't use POCOs then your not really going to be data store agnostic. And using POCOs will allow you to get your system up and running with memory based repositories which is what you'll likely want to use for your unit tests anyhow.
The AutoMapper sounds nice but I wouldn't consider it a deal breaker. Mapping POCOs to EF4, LinqToSql, nHibernate isn't that time consuming unless you have hundreds of tables. When/If your POCOs begin to diverge from your persistence layer then you might find that an AutoMapper wont really fit the bill.
Is every app that allows users to input data built with core data?
I've built a "grocery list" type of table view app where you name the list and then in a detail view add items to the list. Simple.
What I don't get is this, based on an iphone development book the example saves the data to a plist using dictionaries.
I've learned that it works on the simulator but not the device because the data is saved to the application bundle not the document directory (which was new to me!)
On the device the app works great except-it won't HOLD the data.
Is core data or sqlite the only solution?
Is every app that allows users to input data built with core data?
Note that your question as posed is incorrect, as it assumes that CoreData is tied to SQLite and is an alternative to plists.
CoreData is a framework for object lifecycle and graph management. It provides implementation of common tasks like changes tracking and propagation, consistency enforcement, data validation and so on.
The CoreData framework is a separate from the object persistence layer and can use different serialization implementations, including SQLite and XML (plists).
For more details, read Core Data Programming - Persistent Store Features.
The decision whether you should use CoreData should be based on whether you need any of the features it provides. If you need to serialize simple object graphs, without consistency requirements, you can use standard NSDictionary to serialize your data in a simple plist file in any of the application-writable folders. Otherwise, use CoreData, and choose the proper persistent store based on the type of data you will be storing.
From what I've seen around the internet, you can use Core Data (which gives you the options of SQLite, atomic, and XML), you can use NSKeyedArchivers and NSKeyedUnarchivers (http://www.vimeo.com/1454094) or you can store the data inside the local application folder (possibly using a serialization method). It looks like Core data is the best solution, but a more complex one to implement. For a simple app, as yours is, I think serializing data and storing it in the local app directory would be perfect.
I am surprised that your book is showing an example where user data is written to the app bundle. Actually, I'm a little surprised that that is even possible.
You should be able to write your data to an NSDictionary (or NSMutableDictionary) and then write that to your app's Documents directory, using -writeToFile:atomically:
Reading data back in should also be straightforward, using -initWithContentsOfFile:.
For someone just getting started, I would recommend keeping it simple. Working NSDictionary is very simple, though you have to manage things like the list of lists and how to name lists that are stored in Documents directory, etc.
Ultimately, using Core Data would probably be a better approach. It offers more flexibility and more power - but, as ever, those advantages come at a cost.
Your question is very important to the community in the respect that
you are asking a strategic question: which technology do I use, when?
Core Data is best for the day-to-day work of a list-based app. Core data is built to mirror the storage of data, similar to how databases work. Relational structures, sorting, key indexing and other row-based attributes are best supported by Core Data.
Property Lists (*.plist) is best suited to one-time updates to critical environmental settings. The user, for example, can optionally set .plist attributes through IOS Settings app. So passwords, account settings, email addresses, and configuration options can be set here nicely. This kind of data is very different from frequently-updated, transactional data.
XML Persistence is closely related to .plist, in that the property list (or .plist) is an xml file in itself. Hence, you could download a stream of xml data, then use it in your app using the same programming rubric as you would, adjusting a property list. Hence, receiving xml data from the web, or uploading such a list, maps nicely to xml persistence.
AWS also proposed the AWS-Persistence library, to support synchronizing your core data collections with their online databases. This could provide helpful by 1) having a user populate data locally via Core Data, then lazily/opportunistically uploading the list. For your purposes (grocery shopping list), this could provide immediacy to the user, while giving your server an interesting big-data opportunity (analyze user transactions, provide recommendations, sell ads, etc).
Hope this gets future visitors tapping into the wealth of what IOS provides -- peace!