I’m trying to make a POST request via Guzzle to a Yii controller but getting a "Bad Request #400". I thought when I don’t use behaviours() the controller is automatically accessible to all kinds of requests, but nope. How I can solve this? What would be best practice for CURL/Guzzle requests in Yii2?
class ImportController extends yii\web\Controller {
public function actionIndex() {
return 'OK';
}
}
You should create a rest controller instance (yii\rest\ActiveController) and implement authentication for it as described here: https://www.yiiframework.com/doc/guide/2.0/en/rest-authentication
That is probably the correct approach to your use case, and you would not have to deal with CSRF.
Related
I am trying to build a GitHub application that will handle webhook events and a few other things not related to GitHub. My app has a GitHub controller that should handle all webhook events, but the GH sends all this in one URL.
The way to tell what event we should process is by checking the 'X-GitHub-Event' header value, and I am looking for the most straightforward option to route based on this.
I wouldn't say I like having one #Post() route and using logic inside the method to check the header and call proper service; this way, the controller's method would become huge.
What I am looking for is something like this:
#Controller('github')
public class GitHubController {
#Post()
#GitHubEvent('pull_request')
public processPR() {...}
#Post()
#GitHubEvent('comment')
public processComment() {...}
}
I'm using WebFlux to create a REST controller. My question is, how do I handle request parameters/request body? Can I pass them like the old way and remain reactive?
#PostMapping("/register")
Mono<User> register(#Valid #RequestBody UserRegistrationDto userRegistrationDto) {
return userService.registerUser(userRegistrationDto);
}
Or do I need to read the UserRegistrationDto from org.springframework.web.reactive.function.server.ServerRequest and do the validation manually? Maybe my method should accept Mono<UserRegistrationDto>?
You have a choice, if you prefer the 'old' way of RestControllers then the way you posted is just fine. If you prefer the new way of handlers and routes then you would need a serverRequest.bodyToMono as you stated.
I've built my first grails application. My URL mappings are what the default application provides:
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
}
Senario
I have a controller called ColorController with actions save and list. It simply does something like this:
def save () {
def colorInstance = new Color(params)
colorInstance.save(flush: true)
}
def list () {
[colorList: Color.list, colorTotal: Color.count()]
}
I would like to build a simple API for these actions.
The save action should accept parameters as JSON and provide a successful message if the records save.
The list action should provide the list as JSON
Questions
Should I make a separate URL mapping for api? (e.g. http://<domain>/<app>/rest/controller/action)
Should I be making a separate controller for my API's
I am using spring security plugin for authentication. But at some point I might want to authenticate the restful api as well. What are some solutions for that?
If I use the same controller, how can I modify these simple actions to do what I need.
Before even looking below for my opinion/answers I would suggest to visit this SO Question for the basic understanding of RESTful WS in Grails.
Opinions:
"The save action should accept parameters as JSON and provide a successful message if the records save" - Save is mapped to POST RESTful. Instead of binding a JSON body to params it is bound to the request. In order to access the JSON object you just need to use request.JSON in the action method.
request.JSON instanceof JSONObject
"The list action should provide the list as JSON" - list() action is mapped to a GET Request and you can render the map as JSON in the list() as below
//Controller list()
import grails.converter.JSON
def list () {
[colorList: Color.list, colorTotal: Color.count()] as JSON
}
Answers to Questions:-
Should I make a separate URL mapping for api?
Abiding by the basics of REST, the client should only access the resource (Color in this case) and should not bother about the underlying controller or action. The server side logic should be abstracted from the client. URL Mapping is what the client would use to as form of request. I would have something like this in my url mapping for Color Resource.
/color/$id?(resource: "color")
or
/color/$id?(controller: 'color'){
action = [GET: "list", POST: "save"]
}
Should I be making a separate controller for my API's? - Depends on the way the App is designed. You also can have the above controller as the API. For example, currently I am working on a grails app which used AngularJS in the front End which connects to the Grails APP RESTFully. In order to achieve I had a RestClientController which works as an API to Angular. The rationale behind having a REST api in the same app is that in future we can expose the underlying service to external clients other than the Angular client present in the app itself.
I am using spring security plugin for authentication. But at some point I might want to authenticate the restful api as well. What are some solutions for that? - You can use Spring Security here as well. In my case I am using the plugin and I secure the controller by using the plugin's annotated component #Secured. I have custom OAuth enabled as well for authorization which interacts to the company wide LDAP and AD Groups.
If I use the same controller, how can I modify these simple actions to do what I need. - I think you would have got the answer to this question by now (after going through the SO question I mentioned above). Here is my opinion, controller actions can route to appropriate service classes which does the business implementations based on the request parameters.
For example,
//Action
def show(){
if(params.id){
colorService.getColor()
} else {
colorService.searchColor()
}
}
In the above example, the url mapping would be /color/123 or /color. In the former case, it will get the color and in the later it will search the colors
I can no longer do POSTs to the WebAPI in MVC 4. The Post() method, however I make it, will not be invoked. If I send a GET, there are no problems at all.
public void Post()
{
}
That is how simple it is in the controller. I use Fiddler to send the Post, but no reaction. I use fiddler to send a GET to the same controller, and the GET method gets invoked.
I have looked around for hours, but cannot figure out where the problem is, let alone where to do the debugging, because any POST simply has a 500 (Internal Server Error) returned.
Any ideas on what is going on here?
I had two more methods in the controller, one called GatherZipCode() and another called RetrieveWeather(). I thought they had no influence on handling POST, since they did not have the Post keyword in them. But they confused it all, and the reason for the problems. So watch out for having more than one handler of a Post in the api controller.
Thanks to Darin Dimitrov, who led me on the right track.
add a method atrribute:
[HttpPost]
public void Post()
{
}
I have a RESTful WCF service with many different functions. For each function I need to call an authentication method that I have written. I can manually call this method on every request but I was looking for a way to force the WCF engine to call this method before these functions are entered. Does anyone know if this is possible?
Cheers
You could use the "Custom Behavior" approach.
You would need to write a Class that implements IDispatchMessageInspector. The following MSDN magazine article gives a nice explanation of this: Extending WCF with Custom Behaviors (link points to Wayback Machine cached copy; downloads likely don't work).
To force WCF REST Service to first call a method especially if it's for authorization
customize/override CheckAccessCore method of System.ServiceModel.ServiceAuthorizationManager
refer: http://msdn.microsoft.com/en-us/library/ms731774(v=vs.110).aspx
If it's for authorization, can't you use the built in services?
For instance, there is the PrincipalPermission attribute. Does that help in your case?
You could think about creating a WCF routing service. You would call a fixed endpoint - your authentication method - and then from there on, route your calls to the actual methods, based on some indication in the request.
For .NET 4, the Routing Service functionality will be included into WCF out of the box.
What I don't know is how that all matches REST, though.
I came across this post, while searching for the same thing.None of the answer's were simple/quick solution so if you just want a function to be called before every method then you can do what i just did:
I created a zero argument constructor:
public class myService : ImyService
{
myService ()
{
ConnectToDatabAse();
FunctionYouWantToCallBeforeEveryMethodCall();
//Add here more
}
}