NeVeSpl / NTypewriter

File/code generator using Scriban text templates populated with C# code metadata from Roslyn API.
https://nevespl.github.io/NTypewriter/
MIT License
126 stars 25 forks source link

Is there a way to simulate Typewriter's RequestData for a controller method? #17

Closed gregveres closed 3 years ago

gregveres commented 3 years ago

This is the typewriter code for processing my Controllers. In typewriter I had to break out processing the methods twice for each method type because some controller actions required sending data and some didn't. Typewriter had a method called Method.RequestData() that would the data that would have to be sent in the body of the post/put request.

I was looking at the Parameters to see if there was a flag that indicated a [FromBody] attribute or something but I don't see any way other than maybe looking at the Parameter's type and using IsPrimitive, but even that misses the [FromBody] attribute, I think.

I am open to any suggestions, even suggestions of "write a custom function to do ..."

This is what my Typewriter script looked like:

import axios, { AxiosResponse } from 'axios';
$Methods(m => (m.HttpMethod() == "post") && m.RequestData() != "null")[
// $HttpMethod: $Url
export const $RouteName = ($Parameters(p => p.Type.IsPrimitive)[$Name: $QualifiedType][, ]) => `/$Url`;
export function $MethodName($Parameters[$Name: $QualifiedType][, ]): Promise<$ReturnType> {
  return axios
    .post($RouteName($Parameters(p => p.Type.IsPrimitive)[$Name][, ]), $RequestData)
    .then((r: AxiosResponse<$ReturnType>) => {
      return r.data;
    });
}]
$Methods(m => (m.HttpMethod() == "post") && m.RequestData() == "null")[
// $HttpMethod: $Url
export const $RouteName = ($Parameters(p => p.Type.IsPrimitive)[$Name: $QualifiedType][, ]) => `/$Url`;
export function $MethodName($Parameters[$Name: $QualifiedType][, ]): Promise<$ReturnType> {
  return axios
    .post($RouteName($Parameters(p => p.Type.IsPrimitive)[$Name][, ]))
    .then((r: AxiosResponse<$ReturnType>) => {
      return r.data;
    });
}]
gregveres commented 3 years ago

Do you have a sample .nt file that creates method calls to your back end? I could really use the help figuring out how to get the right data out of the data model.

Thanks for the Url fix BTW.

NeVeSpl commented 3 years ago

There is no straight forward replacement for typewriter RequestData.

In general, the code model does not know anything about TS/ASP specific things. All auxiliary TS/ASP things are located in built-in functions.

To get the parameter that is sent by body you can use Action.BodyParameter

And here you can see how I generate API calls: ServiceTemplate.nt

gregveres commented 3 years ago

Thank you. I have looked through your ServiceTemplate.nt and I think I see a path forward.

Great work, btw, on NTypewriter. I really appreaciate someone picking up where Typewriter left off.

gregveres commented 3 years ago

Ok, I am done with the Services.nt file now. Seeing your example made the world of difference. If you don't mind sharing those samples with people, I would really suggest that you link to ServiceTemplate.nt. DTOTemplate.nt, and EnumTemplate.nt in the docs on the front page of the project. If I had seen those files at the beginning, it would have saved me at least a day of learning and experimenting.

This is a great tool. I am happy I have something to migrate to from Typewriter.

NeVeSpl commented 3 years ago

It is too early to make an opinionated suggestion on how templates should like. I would like people to explore and experiment on their own. Yes, it makes the learning curve steeper for a user, but it gives more time/opportunities for NTypewriter to mature/evolve before wider adoption by the community.

gregveres commented 3 years ago

Fair enough. Is there some way I could send you my templates when I am done so that you have another set of examples for inspiration for improvements?

For instance, I want my services class to have both the end point method and another method that returns the url to that end point with the appropriate parameters. I am struggling to figure out how to not have the body parameter included in the list of parameters for the Url.

I wonder if it would make sense to have a Action.UrlParameters function that provides the list of parameters that are needed for the url creation.