Unlike the property API, when the identity of the people was key to the API.
For example, to update an existing bank customers address, a POST request can be made to ChangeOfAddress resource. It is very important to distinguish between resources in REST API and domain entities in a domain driven design.
how many of them happened?
When adding the range index use type = date, no namespace (for this example), localname = posted-date, and leave other values as the default. The main reason for this approach is readability; a nested resource URL can convey that one resource belongs to another one. Now that we have a values option set up, there are two ways to apply an aggregation function to it. MarkLogic and the MarkLogic logo are trademarks of MarkLogic Corporation. Note: When we talk about preventing business logic migration, we are talking about the control flow business logic (for example, making all the required API requests in correct sequence) and not the functional business logic (for example, tax calculation). To sum it all up, we want to use nested resources to improve readability and in turn developer experience and sometimes we even have to use them because the data-source doesnt give us a way to identify a nested resource solely by their ID. This allows us to model business processes as true resources which can be tracked in their own right. If we dont have the Customer enrollment process modeled as a resource, the API consumer has to then know the business logic that a customer enrollment involves - one request to create customer resource, one request for KYC request, one request for print card request, etc.
And such a process should be modeled as a resource in its own right. Be the first to know! Disclaimer: The statements and opinions expressed in this article are those of the author(s) and do not necessarily reflect the positions of Thoughtworks. Let us consider two other examples from the same banking domain: In both these cases, rather than using the Account resource, we are using a resource which is the equivalent to a command to deposit money or transfer money - Transaction resource (similar to CustomerEnrollment mentioned previously). Originally the starters were entities (they had identity) and were associated with the meal. GitHub APIis a good example of a reasonably well designed API in the public domain with right resource granularity. Houses, for example, have house-numbers, but they are local to the streets they belong to. Given that business logic can undergo changes, this approach can increase maintenance efforts - especially when there are different types of API consumers (native mobile, web, etc.) Make simple, powerful, and immediate changes to any aspect of how information is interpreted and acted on. The starting point in selection of resources is to analyze your business domain and extract the nouns that are relevant to your business needs. It also reads better: CustomerEnrollment number 2543 for customer xxxx.
This problem can be solved via HTTP redirects, so all representations are returned from a central root resource and can be cached, but there is still code needed to implement this.
This also plays very nicely withevent sourcing- events are a canonical example of first class citizen nouns and help us get out of the mindset of thinking of them as "mutators" - they're domain relevant events, not just a change to the state of some object. As discussed earlier, changing a customers mailing address is a POST to a new ChangeOfAddress resource, not a PUT of a Customer resource with a different mailing address field value. By continuing to use this website you are giving consent to cookies being used in accordance with the MarkLogic Privacy Statement. Everyone then just POSTs their 'intents' or publishes the resource states they themselves own, perhaps for polling. Since this decision can have a considerable impact on many parts of your API, like security, maintainability or changeability, I want to shine some light on this topic in hopes that it helps to make this decision more educated. To transfer money, we can post to /transactions or /accounts/343/transactions and create a new Transaction (or MoneyTransfer) resource. Let us consider an example - setting up a new customer in a bank. A rule of thumb is a maximum nesting depth of two. Reified resources can be used as the transactional boundary for your service.
A resource can be a singleton or a collection. Or it could be that we have the CustomerChange resources that actually mutate the state of Customer in DB, in which case the GET is a direct DB retrieval.
If comments have globally unique IDs, we could query them directly. In the first approach, a CRUD API built around the Customer resource can be used to directly update the address of the customer.
a person), and so on. Need to know to enable it?
Sometimes it cant be avoided, because the data-source simply doesnt gives us any other choice, but if we have the choice we should consider all the pros and cons. Although a good start, we need to figure out what we can do with these functions. The procedure to use those is pretty similar, except that you dont have to specify the aggregatePath or udf attributes that youll see below. The business equivalent of such a resource is a typical form that we may fill out in a business, which triggers a business process. This is just the same as in-memory object design. How can we do this? In other words, reification makes something abstract (e.g. In many cases, this can make debugging easier. Weve already discussed having a Transaction resource for money deposit, and there are many good reasons for doing so. But what's wrong with this? Developer experience. Business Processes are of course behavior and the business language often focuses on the verb. What happens when I get the property: I don't know who lives there, but my common use case is that I always want to list the people living there! For example, sub-collection resource accounts of a particular customer can be identified using the URN /customers/{customerId}/accounts (in a banking domain). If the API consumer makes a request to create the blog post but does not make an API request to attach the tags, then the blog post is left with inconsistent data (when tags are mandatory in the context of application). This may mean separating resources out into more resources according to who truly owns the particular bit of state.
Lets change the API to allow you to order the meal in one go: Brilliant - we've reduced the number of messages to order a email. If we go with this CRUD API design, the business meaningful event data such as when was the address changed, who changed it (changed by customer or by the bank staff), what was the change, history of changes, etc.
"today's weather in Los Angeles"), a collection of other resources, a non-virtual object (e.g. Many questions arise when we start designing an API, especially if we want to create a REST API and adhere to the REST core principles: One topic in this space that is debated quite often is the nesting of resources also called sub-resources.
This makes the client code more brittle. While nesting is sometimes necessary and cant be avoided, it is often a choice that comes with specific costs or dangers we should keep in mind. This doesnt lead to a question of feasibility in terms of skills or know-how, but often simply questions of development and maintainence costs.
Does our blog with ID X have an article with ID Y? These verbs can be nicely mapped to HTTP verbs.
Sometimes this can be useful, but more often than not we want to keep our URLs so old links wont stop working. Instead of using the Customer resource, we are using a resource which is the equivalent of a request to enroll customer. With additional input from: Jonny Leroy, Sriram Narayan andTarek Abdelmaguid. Resource modeling requires a careful consideration based on the business needs, technical considerations (clean design, maintainability, etc.)
Interestingly, we changed our model when we changed the API. This requires making just one API request to the API provider reducing the load on the server. A good example of reified resource is CustomerEnrollment that we discussed previously. The question is what do you want to do with it. If a hierarchy is encoded in an URL we can drop parts of the URL to climb this hierarchy up.
It also usually throws away a lot of information that was available at the time the update was triggered - what was the real business domain event that triggered this update? News, product information, and events delivered straight to your inbox. 2022 MarkLogic Corporation.
Does our article with ID Y have a comment with ID Z? For example,creating a forkis an asynchronous operation. Multiple endpoints that return the same representations can also lead to problems with caching and can violate one of the core principles of RESTful API design. The REST API is configurable so that we can get back what we want. Now that we talked about the reasons why we should use nesting, its also important to talk about the other side: Why should we not nest our resources?
In this situation, there should be a very clear agreement on what the API consumer is expected to do?
will get missed out. and when API consumers may be unknown / more in numbers (for public APIs). Can the API consumer retry? In the meal example, the starters turned out not to be entities, so having an API to create them separately would be odd. API Simulation + Contact Testing = Happiness. But its also perfectly valid for money deposit to be handled by a post to the Account resource. Read over the documentation that provides an overview over the features of the REST API and how its used. This involves updating two low level resources (from account and to account), also involves business validations, creation of transaction entry, sending notifications, etc. It can also violate another core principle, the Uniform Interface. , What do I do if I don't have enough nouns? This is probably a more concrete example where we may model the process as a resource. The HAL specification provides the _embedded keyword for this: This makes it clear that the people aren't part of the resource. API design should be independent of the underlying design concerns on API implementation and data persistence. It is very important to select the right resources and model the resources at the right granularity while designing the REST API so that the API consumers get the desired functionality from the APIs, the APIs behave correctly and the APIs are maintainable. How do we ensure coarse grained interactions with many nouns and few verbs? The client shouldn't be manipulating internal representation; it should be a source of user intent. For example, API consumer can open an account by creating an instance of Account resource using HTTP POST method. Especially in rather complex systems with many relationships between the resources the nested approach can lead to rather long and complicated URLs. Youll find instructions for that here.
API consumer can withdraw or deposit money using HTTP PUT / PATCH / POST methods.
Now we can make the same call as we did above, but in addition to the values, well also get the aggregation function results. In general, using nested resources isnt as flexible as using root resources only. The client shouldn't be manipulating internal representation; it should be a source of user intent. One of the key switches in thinking is to understand that there is an infinite URI space that you can take advantage of. While this doesnt seem to be a problem with one-to-many relationships, in which one part of the relationship cant have multiple connections, we can still get at a point where we want to search for all records of a nested resource across its parent resources. Eventually you run into concepts which are not covered by the usual / obvious nouns. That is, to update an existing customers address, a HTTP PUT request can be made to Customer resource (or Address resource if it exists).
When the event data is not required for business, it is optional to persist ChangeOfResource event data. Getting all comments on all articles of all blogs is also a problem. in a blogging domain. But, now the client want to change their starter, they want to remove the salad.
This posts the contents of the options $data to the REST app server.
However, this simplistic approach may be valid at an abstract level, but breaks down once you hit more complicated domains in practice.
The way to escape low-level CRUD is to create business operation or business process resources, or what we can call as "intent" resources that express a business/domain level "state of wanting something" or "state of the process towards the end result". The first bit of set up is to build and load the custom function. After that, we will talk about the reasons that make nested resources problematic. In summary, PUT puts too much internal domain knowledge into the client as discussed earlier.
You have an API that allows to you create a meal, and then add starters to it: This API shows a pretty standard example of creating resources which are associated in a one-to-many relationship. You may want to get just the results of the aggregation function without the full list of values. With this approach, we can change the relationships via one single endpoint but link our other resources directly via their own root resource that isnt affected by this change.
On the other hand, if we design the API based on very coarse grained resources (designed to do everything) there will not be enough variations to support all the API consumers needs and the API may become too difficult to use and maintain. Theres another aspect to this - the way you organize the server behavior is separate to how the API works.
This article significantly borrows from the discussion points of Thoughtworks employees Charles Haynes, Duncan Cragg, Evan Bottcher, Graham Brooks, James Lewis, Martin Fowler, Peter Gillard-Moss, Samir Seth, Sam Newman, Sarah Hutchins, Srinivasan Raguraman and Tarek Abdelmaguid in internal Thoughtworks developer group discussions, which the articles author was part of. Multiple endpoints increase the effort for the API owner to document the whole thing and make onboarding for new customers much more troublesome.
If we design the API around fine grained resources, we would end up with a chattier API for consumer applications.
Open a new Query Console tab and run the following XQuery code: Change the username and password as needed if you use something other than the admin user, youll need a user with at least the rest-writer role. This is clearly error prone. On the other hand, GitHub also supports many low level resources such asTag. With the single coarse grained POST resource approach, to add a comment or to like a blog post, the API provider has to provide an option for the API consumer to indicate that the API request is meant to add a comment or to like a post - may be by specifying a separate XML element or JSON property in the payload that will indicate the payload type. Specifying view=aggregate skips the full listing of the values. But they are also "things" to the business. Similarly, there are many situations where using HTTP PUT on low level domain resources may be appropriate and simple. Let us relook at what Roy Fieldings dissertation says about resource: any concept that might be the target of an author's hypertext reference must fit within the definition of a resource.. The service that handles the Account is then responsible for coordinating the changes and create a Transaction resource, Notification resource, etc. At the same time, it is good to avoid resource proliferation that may add confusion to the API design. Well change the options that we set up above so that our function gets called. When they don't map nicely, we could approximate.