Is it essential to send response data to dto when working with graphql? - graphql

Hi I am making api server with nestjs and graphql.
I have a question.
When the api server passes the response to the stack above.
Is it right to load the response into the dto?
If question number one is correct, what is the best way?
Or does the graphql schema type play the role of dto?
let me know thank you!

A DTO is an object that helps developers and consumers know what shape the data is going to be in as it goes "over the wire" (when the request or response is made). In GraphQL we use schemas to be our DTOs and follow the GraphQL Query Language spec so that our GraphQL server will know how to deserialize incoming requests and serialize outgoing ones in accordance to the shcemas we create. The only thing that matters in the end is that the data is the correct shape^, not that it's an instance of a class that we created for the sake of the server. With NestJS, it depends if you take the code-first or schema-first approach, but generally in the code-first approach it can be said that your GQL Schema is your DTO. From there, as long as the data looks like the DTO you should be fine.
^ excluding the use of nested schemas which can become problematic if you are trying to return raw JSON and nothing else

Related

Entities or Models in NestJs code first GraphQl

I am new to NestJs and GraphQl, I am learning going over some tutorials. It appears to be an inconstancy in the usage of the terminology model or entity. The nestjs schematics resource generator for graphql code first produces entities, yet the example shown on their website use models.
produces entities:
nx generate #nestjs/schematics:resource generated --language=ts --type=graphql-code-first
uses models no mention of entities in code first approach
https://docs.nestjs.com/graphql/resolvers
which one terminology is most appropriate?
Thank You,
Michael
Both are generally correct. It comes down to naming preferences.
I view entities as database entities, or database table maps. They map from your database data to a class representation that your code will understand. Models can also be used for this, which I believe is the term that sequilize and mongoose prefer to use.
Models, as described in the docs you linked, are generally your DTOs, your schema objects that you expect the API to accept and respond with.
You'll notice that the generator also generates two #InputType() files as well, which will be more closely tied to your incoming DTO while the entity.ts will be closer to your response DTO.
So, both are correct, and it comes down to naming preferencec.

Is it okay for a resolver to have side effects besides resolving the type?

When creating a GraphQL mutation or query, you usually retrieve or save data. But let's assume I would like to send an e-mail when the data is saved or perform some additional side effects.
Is it common practice for resolvers to have these kind of side effects? Since resolvers should only resolve data according to the SOLID principle, right?
If it turns out that the resolver should not have side effects like these, then where would the side effects belong?
Most tutorials and articles online, including the official tutorial of GraphQL itself, don't seem to cover this or take it into account.
Many thanks!
It depends on that resolver is resolving fields of what types.
If it is resolving the fields of the root mutation ,it must involve sides effects as mutation is supposed to modify server-side data. So it is okay to send an email in root mutation field 's resolver.
For the resolver of object type and root query fields , as it is supposed to only retrieving data, it is awkward for me if they have any side effects.

How to improve the gRPC development?

I find it's tedious to define the protobuf message again in the .proto file after the entity model is ready.
For example, exposure the CRUD operations through gRPC you need to define the table schema in .proto files in a message way because gRPC requires it.
In traditional restful API development, we don't need to define the messages because we just return some json, and the json object can be arbitrary.
Any suggestions?
P.S. I know the gRPC is more efficient than restful APIs at run time. However I find it's far less efficient than restful APIs at development time.
Before I found the elegant way to improve the efficiency I currently use an ugly way: define a JSON message type:
syntax = "proto3";
package user;
service User {
rpc FindOneByJSON(JSON) returns (JSON) {}
rpc CreateByJSON(JSON) returns (JSON) {}
}
message JSON {
string value = 1;
}
It's ugly because it need the invoker to JSON.stringify() the arguments and JSON.parse() the response.
Because gRPC and REST follow different concepts.
In REST, the server maintains the state and you just control it from the client (that's what you use GET, POST, PUT, UPDATE, DELETE request types for). In contrast, a procedure call has a well-defined return type that is reliable and self-describing. gRPC does not follow the concept of the server being the single source of truth concerning an object's state; instead -- conceptually -- you can interact with the server using regular calls, as you would on a local setup.
By the way, in good RESTful design, you do use schemas for your JSON returns, so in fact it is not arbitrary, even though you can abuse it to be. For example, check the OpenAPI 3 specification for the response object definition: They usually contain references to schemas.

updates to entity,domain driven design

Lets say I have an order which got updated on the UI with some values (they could be ok/not ok to ensure save)
1. How do we validate the changes made? Should the DTO which carries the order back to service layer be validated for completeness?
Once the validation is complete? How does the service return the validation errors? Do we compose a ReponseDTO object and return it like
ResponseDTO saveOrder(OrderDTO);
How do we update the domain entity order? Should the DTO Assembler take care of updating the order entity with the latest changes?
If we imagine a typical tiered' approach, ASP .NET on Web Server, WCF on Application Server.
When the Order form is updated with data on the web and saved. The WCF receives a OrderDTO.
Now how do we update the order from DTO? Do we use an assembler to update the domain object with changes from DTO? something like
class OrderDTOAssembler {
updateDomainObject(Order, OrderDTO)
}
I will try answer some of your questions from my experience and how I should approach your problem.
First I should not let DTO conduct any validations, but just plain POCO DTO's usually have different properties with specific datatypes, so some kind of validation is done. I mean you have to apply an integer street number and string for street name etc.
Second as you point out. Let a ORderDTOAssembler convert from OrderDTO to Order and vice versa. This is done in the application layer.
Third I would use Visitor pattern Validation in a Domain Driven Design like the example. The OrderService will use an IOrderRepository to save/update the order. But using the visitor-validation approach the OrderService vill call Order.ValidatePersistance (see link in example - but this is a extension method that is implemented in infrastructure layer since it has "db knowledge") to check its state is valid. If true, then we to IOrderRepository.Save(order).
at last, if Order.ValidatePersistance fails we get one or more BrokenRules messages. These should be returned to client in a ResponseDTO. Then cient can act on messages and take action. Problem here can be that you will have a ResponseOrderDTO messages but maybe (just came up with this now) all your ResponseDTO can inherit from ResponseBaseDTO class that expose necessary properties for delivering BrokenRule messages.
I hope you find my thoughts useful and good luck.

Expose IQueryable Over WCF Service

I've been learning about IQueryable and lazy loading/deferred execution of queries.
Is it possible to expose this functionality over WCF? I'd like to expose a LINQ-to-SQL service that returns an IQueryable which I can then perform additional queries on at the client, and finally execute using a .ToList(). Is OData format applicable at all in this context?
If possible, what is the term for this technique and what are some good tutorials I can follow? Thank you.
You should check WCF Data Services which will allow you to define Linq query on the client. WCF Data Services are probably the only solution for your requirement.
IQueryable is still only interface and the functionality depends on the type implementing the interface. You can't directly expose Linq-To-Sql or Linq-To-Entities queries. There are multiple reasons like short living contexts or serialization which will execute the query so the client will get list of all objects instead of the query.
as far as i know, the datacontext is not serializable meaning that you cannot pass it around with WCF
You can use http://interlinq.codeplex.com/ which allows you to send Linq query over WCF.
WCF Data Services only can be using with webHttpBinding and not all Linq queries can be expressed. Writing queries when WCF Data Service is used is not so attractive - requires string expressions such as:
.AddQueryOption("$filter", "Id eq 100");
https://remotelinq.codeplex.com/ is another choice. But it works in AppDomain to scan the Current Assemblies and serialize them. This tech is not suitable to WinRT as no Domains for WinRT App
I've been struggling with the same question, and realized that a well formed question is a problem solved.
IQueryable basically serves to filter the query before sending it to your DB call so instead of getting 1000 records and filter only 10, you get those 10 to begin with. That filtering belongs to your Service Layer, but if you are building an API I would assume you would map it with AND/OR parameters in your URL.
http://{host}/{entity}/q?name=john&age=21.
So you end up with something like this:
Filter:Column1=Value1 > http://{host}/{entity}q?column1=value1 > SELECT *
FROM Entity
WHERE Column1=Value1
MVC > WCF > DB
You can find a very good sample [here]
Lastly, since your payload from the WCF will be most likely a JSON, you can (and should) then deserialize them in your Domain Models inside a collection. It is until this point where the paging should occur, so I would recommend some WCF caching (and since its HTTP, it's really simple). You still will be using LINQ on the WebApp side, just w/o "WHERE" LINQ clause (unless you want to dynamically create the URL expressed above?)
For a complex OR query, you mind end up with multiple WCF queries (1 per "AND") and then concatenate them all together
If it's possible to send IQuerable<> over WCF it's not a good thing security wise, since IQuerable<> could expose stuff like the connection string to the database.
Some of the previous comments seem promising though.

Resources