Skip to content

Commit

Permalink
🚧 Experiment with templates
Browse files Browse the repository at this point in the history
Experiments with using templates. Applies them only to Films and
documents my thoughts.
  • Loading branch information
connorjs committed Sep 10, 2023
1 parent fa77656 commit f79d19c
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 17 deletions.
23 changes: 6 additions & 17 deletions src/films.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,15 @@ using TypeSpec.Http;

namespace SWAPI;

// Dev note: See `operation-template.tsp`

@route("/films")
namespace films {
/**
* Get all the film resources.
*
* @param search Case-insensitive partial match on the `title` field.
*/
@OpenAPI.operationId("ListFilms")
op list(@query search: string): Film[];

@route("/{filmId}")
namespace film {
/**
* Get a specific film resource.
*
* @param filmId Numeric ID of the film to get.
*/
@OpenAPI.operationId("GetFilm")
op read(@path filmId: int32): Film;
}
op list is List<Film>;

@OpenAPI.operationId("GetFilm")
op read is Get<Film>;
}

/** A Film resource is a single film. */
Expand Down
1 change: 1 addition & 0 deletions src/main.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import "@typespec/http";
import "@typespec/openapi";

import "./films.tsp";
import "./operation-templates.tsp";
import "./people.tsp";
import "./planets.tsp";
import "./root.tsp";
Expand Down
39 changes: 39 additions & 0 deletions src/operation-templates.tsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using TypeSpec.Http;

// Dev note: Only `films.tsp` uses these templates due to shortcomings I find
// with the template approach.
//
// - I want `filmId` as the `Get` path parameter, not a generic `id`. I have
// found the specificity helps, especially with code generation.
// - The doc comments can only differ with `{name}`, which prevents deeper
// clarification. For example, the `search` parameter should clarify on which
// fields it searches.
// - The `@OpenAPI.operationId` decorator is not compatible with this reuse
// pattern. The resource route is also needed at the call site.
// _Note: This is why I did not wrap these operations in an interface._
//
// Thus, almost half of the config is still needed/desired at the call site.
//
// Standardization presents a great benefit for this approach, but I’ve found
// independent evolution on top of a copied base proves similarly effective.
//
// I will leave these templates here for reference in the repository.

/** The list operation template. */
@get
@doc("Get all the {name} resources.", TResource)
op List<TResource extends {}>(
@doc("Case-insensitive partial match on selected fields.")
@query
search: string,
): TResource[];

/** The get (read) operation template. */
@route("/{id}")
@get
@doc("Get a specific {name} resource.", TResource)
op Get<TResource extends {}>(
@doc("Numeric ID of the {name} to get.", TResource)
@path
id: int32,
): TResource;

0 comments on commit f79d19c

Please sign in to comment.