web-dev-qa-db-fra.com

Comment mapper correctement les itinéraires d'API Web

Je crée une API pour un site de type Twitter à l'aide de l'API Web et j'ai du mal à cartographier les itinéraires

J'ai les actions suivantes pour le contrôleur utilisateur:

public User Get(string firstname, string lastname)
public User Get(Guid id)
public User Friends(Guid id)
public User Followers(Guid id)
public User Favorites(Guid id)

Les itinéraires souhaités et la documentation générée doivent être:

api/users?firstname={firstname}&lastname={lastname}
api/users/{id}
api/users/{id}/friends
api/users/{id}/followers
api/users/{id}/favorites

Dans WebApiConfig.cs, j'ai:

config.Routes.MapHttpRoute(
    "2",
    "api/{controller}/{id}",
    new { action = "get", id = RouteParameter.Optional }
);


config.Routes.MapHttpRoute(
     "1",
     "api/{controller}/{id}/{action}"
);

Comment mapper les itinéraires WebAPI correctement?

17
Donny

Étant donné la flexibilité que vous souhaitez, vous devriez jeter un œil à

Routage d'attributs dans l'API Web ASP.NET 2

Dans WebApiConfig.cs, activez le routage d'attributs comme

// Web API routes
config.MapHttpAttributeRoutes();

Dans UserController

Remarque étant donné les noms des actions Friends, Followers and Favorites ils impliquent de retourner des collections plutôt qu'un seul utilisateur

[RoutePrefix("api/users")]
public class UserController: ApiController {

    //eg: GET api/users?firstname={firstname}&lastname={lastname}
    [HttpGet]
    [Route("")]
    public User Get([FromUri]string firstname,[FromUri] string lastname) {...}

    //eg: GET api/users/{id}
    [HttpGet]
    [Route("{id:guid}")]
    public User Get(Guid id){...}

    //eg: GET api/users/{id}/friends
    [HttpGet]
    [Route("{id:guid}/friends")]
    public IEnumerable<User> Friends(Guid id){...}

    //eg: GET api/users/{id}/followers
    [HttpGet]
    [Route("{id:guid}/followers")]
    public IEnumerable<User> Followers(Guid id){...}

    //eg: GET api/users/{id}/favorites
    [HttpGet]
    [Route("{id:guid}/favorites")]
    public IEnumerable<User> Favorites(Guid id){...}
}
34
Nkosi

Le routage est sensible à l'ordre. Le match premier gagne toujours. Il est donc important que vous commandiez vos itinéraires du plus spécifique au moins spécifique.

// All parameters are required, or it won't match.
// So it will only match URLs 4 segments in length
// starting with /api.
config.Routes.MapHttpRoute(
     "1",
     "api/{controller}/{id}/{action}"
);

// Controller is required, id is optional.
// So it will match any URL starting with
// /api that is 2 or 3 segments in length.
config.Routes.MapHttpRoute(
    "2",
    "api/{controller}/{id}",
    new { action = "get", id = RouteParameter.Optional }
);

Lorsque vos itinéraires sont ordonnés de cette façon, vous obtiendrez le comportement que vous attendez.

5
NightOwl888

Il existe une variété de documents de référence utiles sur ce sujet, tels que:

Les avez-vous regardés?

Mise à jour ..

Il est préférable d'indiquer explicitement quel paramètre est lequel, c'est-à-dire:

    config.Routes.MapHttpRoute(
        name: "2",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { action = "Get", id = RouteParameter.Optional },
    );

    config.Routes.MapHttpRoute(
        name: "1",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: null
    );

La principale chose que je voyais mal était que vous aviez une action/id dans le mauvais ordre sur la route "1".

1
MikeDub