1674953520
Generate api via swagger scheme.
Supports OA 3.0, 2.0, JSON, yaml
Generated api module use Fetch Api or Axios to make requests.
Any questions you can ask here or in our slack(#swagger-typescript-api channel)
P.S. If you are creating the PR, please check your changes with using command npm run prepare
P.S. If you want to contribute please use the next
branch. All PRs that has target master
will be declined!
Thanks to Jetbrains for providing a free license for their excellent Webstorm IDE.
All examples you can find here
Usage: sta [options]
Usage: swagger-typescript-api [options]
Usage: swagger-typescript-api generate-templates [options]
Options:
-v, --version output the current version
-p, --path <string> path/url to swagger scheme
-o, --output <string> output path of typescript api file (default: "./")
-n, --name <string> name of output typescript api file (default: "Api.ts")
-t, --templates <string> path to folder containing templates
-d, --default-as-success use "default" response status code as success response too.
some swagger schemas use "default" response status code as success response type by default. (default: false)
-r, --responses generate additional information about request responses
also add typings for bad responses (default: false)
--union-enums generate all "enum" types as union types (T1 | T2 | TN) (default: false)
--add-readonly generate readonly properties (default: false)
--route-types generate type definitions for API routes (default: false)
--no-client do not generate an API class
--enum-names-as-values use values in 'x-enumNames' as enum values (not only as keys) (default: false)
--extract-request-params extract request params to data contract (Also combine path params and query params into one object) (default: false)
--extract-request-body extract request body type to data contract (default: false)
--extract-response-body extract response body type to data contract (default: false)
--extract-response-error extract response error type to data contract (default: false)
--modular generate separated files for http client, data contracts, and routes (default: false)
--js generate js api module with declaration file (default: false)
--module-name-index <number> determines which path index should be used for routes separation (example: GET:/fruites/getFruit -> index:0 -> moduleName -> fruites) (default: 0)
--module-name-first-tag splits routes based on the first tag (default: false)
--disableStrictSSL disabled strict SSL (default: false)
--disableProxy disabled proxy (default: false)
--axios generate axios http client (default: false)
--unwrap-response-data unwrap the data item from the response (default: false)
--disable-throw-on-error Do not throw an error when response.ok is not true (default: false)
--single-http-client Ability to send HttpClient instance to Api constructor (default: false)
--silent Output only errors to console (default: false)
--default-response <type> default type for empty response schema (default: "void")
--type-prefix <string> data contract name prefix (default: "")
--type-suffix <string> data contract name suffix (default: "")
--clean-output clean output folder before generate api. WARNING: May cause data loss (default: false)
--api-class-name <string> name of the api class (default: "Api")
--patch fix up small errors in the swagger source definition (default: false)
--debug additional information about processes inside this tool (default: false)
--another-array-type generate array types as Array<Type> (by default Type[]) (default: false)
--sort-types sort fields and types (default: false)
--extract-enums extract all enums from inline interface\type content to typescript enum construction (default: false)
-h, --help display help for command
Commands:
generate-templates Generate ".ejs" templates needed for generate api
-o, --output <string> output path of generated templates
-m, --modular generate templates needed to separate files for http client, data contracts, and routes (default: false)
--http-client <string> http client type (possible values: "fetch", "axios") (default: "fetch")
-c, --clean-output clean output folder before generate template. WARNING: May cause data loss (default: false)
-r, --rewrite rewrite content in existing templates (default: false)
--silent Output only errors to console (default: false)
-h, --help display help for command
Also you can use npx
:
npx swagger-typescript-api -p ./swagger.json -o ./src -n myApi.ts
You can use this package from nodejs:
const { generateApi, generateTemplates } = require('swagger-typescript-api');
const path = require("path");
const fs = require("fs");
/* NOTE: all fields are optional expect one of `output`, `url`, `spec` */
generateApi({
name: "MySuperbApi.ts",
// set to `false` to prevent the tool from writing to disk
output: path.resolve(process.cwd(), "./src/__generated__"),
url: 'http://api.com/swagger.json',
input: path.resolve(process.cwd(), './foo/swagger.json'),
spec: {
swagger: "2.0",
info: {
version: "1.0.0",
title: "Swagger Petstore",
},
// ...
},
templates: path.resolve(process.cwd(), './api-templates'),
httpClientType: "axios", // or "fetch"
defaultResponseAsSuccess: false,
generateClient: true,
generateRouteTypes: false,
generateResponses: true,
toJS: false,
extractRequestParams: false,
extractRequestBody: false,
unwrapResponseData: false,
prettier: { // By default prettier config is load from your project
printWidth: 120,
tabWidth: 2,
trailingComma: "all",
parser: "typescript",
},
defaultResponseType: "void",
singleHttpClient: true,
cleanOutput: false,
enumNamesAsValues: false,
moduleNameFirstTag: false,
generateUnionEnums: false,
typePrefix: '',
typeSuffix: '',
enumKeyPrefix: '',
enumKeySuffix: '',
addReadonly: false,
extractingOptions: {
requestBodySuffix: ["Payload", "Body", "Input"],
requestParamsSuffix: ["Params"],
responseBodySuffix: ["Data", "Result", "Output"],
responseErrorSuffix: ["Error", "Fail", "Fails", "ErrorData", "HttpError", "BadResponse"],
},
/** allow to generate extra files based with this extra templates, see more below */
extraTemplates: [],
anotherArrayType: false,
fixInvalidTypeNamePrefix: "Type",
fixInvalidEnumKeyPrefix: "Value",
codeGenConstructs: (constructs) => ({
...constructs,
RecordType: (key, value) => `MyRecord<key, value>`
}),
primitiveTypeConstructs: (constructs) => ({
...constructs,
string: {
'date-time': 'Date'
}
}),
hooks: {
onCreateComponent: (component) => {},
onCreateRequestParams: (rawType) => {},
onCreateRoute: (routeData) => {},
onCreateRouteName: (routeNameInfo, rawRouteInfo) => {},
onFormatRouteName: (routeInfo, templateRouteName) => {},
onFormatTypeName: (typeName, rawTypeName, schemaType) => {},
onInit: (configuration) => {},
onPreParseSchema: (originalSchema, typeName, schemaType) => {},
onParseSchema: (originalSchema, parsedSchema) => {},
onPrepareConfig: (currentConfiguration) => {},
}
})
.then(({ files, configuration }) => {
files.forEach(({ content, name }) => {
fs.writeFile(path, content);
});
})
.catch(e => console.error(e))
generateTemplates({
cleanOutput: false,
output: PATH_TO_OUTPUT_DIR,
httpClientType: "fetch",
modular: false,
silent: false,
rewrite: false,
})
--templates
This option needed for cases when you don't want to use the default swagger-typescript-api
output structure
You can create custom templates with extensions .ejs
or .eta
Templates:
api.ejs
- (generates file) Api class module (locations: /templates/default, /templates/modular)data-contracts.ejs
- (generates file) all types (data contracts) from swagger schema (locations: /templates/base)http-client.ejs
- (generates file) HttpClient class module (locations: /templates/base)procedure-call.ejs
- (subtemplate) route in Api class (locations: /templates/default, /templates/modular)route-docs.ejs
- (generates file) documentation for route in Api class (locations: /templates/base)route-name.ejs
- (subtemplate) route name for route in Api class (locations: /templates/base)route-type.ejs
- (--route-types
option) (subtemplate) (locations: /templates/base)route-types.ejs
- (--route-types
option) (subtemplate) (locations: /templates/base)data-contract-jsdoc.ejs
- (subtemplate) generates JSDOC for data contract (locations: /templates/base)How to use it:
copy swagger-typescript-api
templates into your place in project
--modular
option)add --templates PATH_TO_YOUR_TEMPLATES
option
modify ETA templates as you like
NOTE:
Eta has special directive to render template in your Eta templates - includeFile(pathToTemplate, payload)
If you want to use some default templates from this tool you can use path prefixes: @base
, @default
, @modular
.@base
- path to base templates@default
- path to single api file templates@modular
- path to multiple api files templates
Examples:
- includeFile("@base/data-contracts.ejs", { ...yourData, ...it })
- includeFile("@default/api.ejs", { ...yourData, ...it })
- includeFile("@default/procedure-call.ejs", { ...yourData, ...it })
- includeFile("@modular/api.ejs", { ...yourData, ...it })
- includeFile("@modular/procedure-call.ejs", { ...yourData, ...it })
- includeFile("@base/route-docs.ejs", { ...yourData, ...it })
- includeFile("@base/route-name.ejs", { ...yourData, ...it })
- includeFile("@base/route-type.ejs", { ...yourData, ...it })
- includeFile("@base/route-types.ejs", { ...yourData, ...it })
--module-name-index
This option should be used in cases when you have api with one global prefix like /api
Example:GET:/api/fruits/getFruits
POST:/api/fruits/addFruits
GET:/api/vegetables/addVegetable
with --module-name-index 0
Api class will have one property api
When we change it to --module-name-index 1
then Api class have two properties fruits
and vegetables
--module-name-first-tag
This option will group your API operations based on their first tag - mirroring how the Swagger UI groups displayed operations
extraTemplates
(NodeJS option)type (Record<string, any> & { name: string, path: string })[]
This thing allow you to generate extra ts\js files based on extra templates (one extra template for one ts\js file)
Example here
generate-templates
commandThis command allows you to generate source templates which using with option --templates
You are able to modify TypeScript internal structs using for generating output with using generateApi
options codeGenConstructs
and primitiveTypeConstructs
.
codeGenConstructs
This option has type (struct: CodeGenConstruct) => Partial<CodeGenConstruct>
.
generateApi({
// ...
codeGenConstructs: (struct) => ({
Keyword: {
Number: "number",
String: "string",
Boolean: "boolean",
Any: "any",
Void: "void",
Unknown: "unknown",
Null: "null",
Undefined: "undefined",
Object: "object",
File: "File",
Date: "Date",
Type: "type",
Enum: "enum",
Interface: "interface",
Array: "Array",
Record: "Record",
Intersection: "&",
Union: "|",
},
CodeGenKeyword: {
UtilRequiredKeys: "UtilRequiredKeys",
},
/**
* $A[] or Array<$A>
*/
ArrayType: (content) => {
if (this.anotherArrayType) {
return `Array<${content}>`;
}
return `(${content})[]`;
},
/**
* "$A"
*/
StringValue: (content) => `"${content}"`,
/**
* $A
*/
BooleanValue: (content) => `${content}`,
/**
* $A
*/
NumberValue: (content) => `${content}`,
/**
* $A
*/
NullValue: (content) => content,
/**
* $A1 | $A2
*/
UnionType: (contents) => _.join(_.uniq(contents), ` | `),
/**
* ($A1)
*/
ExpressionGroup: (content) => (content ? `(${content})` : ""),
/**
* $A1 & $A2
*/
IntersectionType: (contents) => _.join(_.uniq(contents), ` & `),
/**
* Record<$A1, $A2>
*/
RecordType: (key, value) => `Record<${key}, ${value}>`,
/**
* readonly $key?:$value
*/
TypeField: ({ readonly, key, optional, value }) =>
_.compact([readonly && "readonly ", key, optional && "?", ": ", value]).join(""),
/**
* [key: $A1]: $A2
*/
InterfaceDynamicField: (key, value) => `[key: ${key}]: ${value}`,
/**
* $A1 = $A2
*/
EnumField: (key, value) => `${key} = ${value}`,
/**
* $A0.key = $A0.value,
* $A1.key = $A1.value,
* $AN.key = $AN.value,
*/
EnumFieldsWrapper: (contents) =>
_.map(contents, ({ key, value }) => ` ${key} = ${value}`).join(",\n"),
/**
* {\n $A \n}
*/
ObjectWrapper: (content) => `{\n${content}\n}`,
/**
* /** $A *\/
*/
MultilineComment: (contents, formatFn) =>
[
...(contents.length === 1
? [`/** ${contents[0]} */`]
: ["/**", ...contents.map((content) => ` * ${content}`), " */"]),
].map((part) => `${formatFn ? formatFn(part) : part}\n`),
/**
* $A1<...$A2.join(,)>
*/
TypeWithGeneric: (typeName, genericArgs) => {
return `${typeName}${genericArgs.length ? `<${genericArgs.join(",")}>` : ""}`;
},
})
})
For example, if you need to generate output Record<string, any>
instead of object
you can do it with using following code:
generateApi({
// ...
codeGenConstructs: (struct) => ({
Keyword: {
Object: "Record<string, any>",
}
})
})
primitiveTypeConstructs
It is type mapper or translator swagger schema objects. primitiveTypeConstructs
translates type
/format
schema fields to typescript structs.
This option has type
type PrimitiveTypeStructValue =
| string
| ((schema: Record<string, any>, parser: import("./src/schema-parser/schema-parser").SchemaParser) => string);
type PrimitiveTypeStruct = Record<
"integer" | "number" | "boolean" | "object" | "file" | "string" | "array",
string | ({ $default: PrimitiveTypeStructValue } & Record<string, PrimitiveTypeStructValue>)
>
declare const primitiveTypeConstructs: (struct: PrimitiveTypeStruct) => Partial<PrimitiveTypeStruct>
generateApi({
// ...
primitiveTypeConstructs: (struct) => ({
integer: () => "number",
number: () => "number",
boolean: () => "boolean",
object: () => "object",
file: () => "File",
string: {
$default: () => "string",
/** formats */
binary: () => "File",
file: () => "File",
"date-time": () => "string",
time: () => "string",
date: () => "string",
duration: () => "string",
email: () => "string",
"idn-email": () => "string",
"idn-hostname": () => "string",
ipv4: () => "string",
ipv6: () => "string",
uuid: () => "string",
uri: () => "string",
"uri-reference": () => "string",
"uri-template": () => "string",
"json-pointer": () => "string",
"relative-json-pointer": () => "string",
regex: () => "string",
},
array: (schema, parser) => {
const content = parser.getInlineParseContent(schema.items);
return parser.safeAddNullToType(schema, `(${content})[]`);
},
})
})
For example, if you need to change "string"/"date-time"
default output as string
to Date
you can do it with using following code:
generateApi({
primitiveTypeConstructs: (struct) => ({
string: {
"date-time": "Date",
},
})
})
See more about swagger schema type/format data here
❗❗❗ Please use the next
branch :)
If you need to check your changes at schemas in tests
folder before create a PR just run command npm run test-all
This project follows the all-contributors specification. Contributions of any kind welcome!
Author: Acacode
Source Code: https://github.com/acacode/swagger-typescript-api
License: MIT license
1674823445
⚠️ This README may be for the latest development version, which may contain unreleased changes. Please ensure you're looking at the README for the latest release version.
This package contains a set of utilities for generating Go boilerplate code for services based on OpenAPI 3.0 API definitions. When working with services, it's important to have an API contract which servers and clients both implement to minimize the chances of incompatibilities. It's tedious to generate Go models which precisely correspond to OpenAPI specifications, so let our code generator do that work for you, so that you can focus on implementing the business logic for your service.
We have chosen to focus on Echo as our default HTTP routing engine, due to its speed and simplicity for the generated stubs, and Chi, and Gin have also been added by contributors as additional routers. We chose Echo because the Context
object is a mockable interface, and it allows for some advanced testing.
This package tries to be too simple rather than too generic, so we've made some design decisions in favor of simplicity, knowing that we can't generate strongly typed Go code for all possible OpenAPI Schemas. If there is a way to accomplish something via utility code or reflection, it's probably a better approach than code generation, which is fragile due to the very dynamic nature of OpenAPI and the very static nature of Go.
We're going to use the OpenAPI example of the Expanded Petstore in the descriptions below, please have a look at it.
In order to create a Go server to serve this exact schema, you would have to write a lot of boilerplate code to perform all the marshalling and unmarshalling into objects which match the OpenAPI 3.0 definition. The code generator in this directory does a lot of that for you. You would run it like so:
go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@latest
oapi-codegen petstore-expanded.yaml > petstore.gen.go
Let's go through that petstore.gen.go
file to show you everything which was generated.
The /components/schemas
section in OpenAPI defines reusable objects, so Go types are generated for these. The Pet Store example defines Error
, Pet
, Pets
and NewPet
, so we do the same in Go:
// Error defines model for Error.
type Error struct {
// Error code
Code int32 `json:"code"`
// Error message
Message string `json:"message"`
}
// NewPet defines model for NewPet.
type NewPet struct {
// Name of the pet
Name string `json:"name"`
// Type of the pet
Tag *string `json:"tag,omitempty"`
}
// Pet defines model for Pet.
type Pet struct {
// Unique id of the pet
Id int64 `json:"id"`
// Name of the pet
Name string `json:"name"`
// Type of the pet
Tag *string `json:"tag,omitempty"`
}
// Type definition for component schema "Pets"
type Pets []Pet
It's best to define objects under /components
field in the schema, since those will be turned into named Go types. If you use inline types in your handler definitions, we will generate inline, anonymous Go types, but those are more tedious to deal with since you will have to redeclare them at every point of use.
For each element in the paths
map in OpenAPI, we will generate a Go handler function in an interface object. Here is the generated Go interface for our Echo server.
type ServerInterface interface {
// (GET /pets)
FindPets(ctx echo.Context, params FindPetsParams) error
// (POST /pets)
AddPet(ctx echo.Context) error
// (DELETE /pets/{id})
DeletePet(ctx echo.Context, id int64) error
// (GET /pets/{id})
FindPetById(ctx echo.Context, id int64) error
}
These are the functions which you will implement yourself in order to create a server conforming to the API specification. Normally, all the arguments and parameters are stored on the echo.Context
in handlers, so we do the tedious work of unmarshalling the JSON automatically, simply passing values into your handlers.
Notice that FindPetById
takes a parameter id int64
. All path arguments will be passed as arguments to your function, since they are mandatory.
Remaining arguments can be passed in headers, query arguments or cookies. Those will be written to a params
object. Look at the FindPets
function above, it takes as input FindPetsParams
, which is defined as follows:
// Parameters object for FindPets
type FindPetsParams struct {
Tags *[]string `json:"tags,omitempty"`
Limit *int32 `json:"limit,omitempty"`
}
The HTTP query parameter limit
turns into a Go field named Limit
. It is passed by pointer, since it is an optional parameter. If the parameter is specified, the pointer will be non-nil
, and you can read its value.
If you changed the OpenAPI specification to make the parameter required, the FindPetsParams
structure will contain the type by value:
type FindPetsParams struct {
Tags *[]string `json:"tags,omitempty"`
Limit int32 `json:"limit"`
}
There are a few ways of registering your http handler based on the type of server generated i.e. -generate server
or -generate chi-server
Echo
Code generated using -generate server
.
The usage of Echo
is out of scope of this doc, but once you have an echo instance, we generate a utility function to help you associate your handlers with this autogenerated code. For the pet store, it looks like this:
func RegisterHandlers(router codegen.EchoRouter, si ServerInterface) {
wrapper := ServerInterfaceWrapper{
Handler: si,
}
router.GET("/pets", wrapper.FindPets)
router.POST("/pets", wrapper.AddPet)
router.DELETE("/pets/:id", wrapper.DeletePet)
router.GET("/pets/:id", wrapper.FindPetById)
}
The wrapper functions referenced above contain generated code which pulls parameters off the Echo
request context, and unmarshals them into Go objects.
You would register the generated handlers as follows:
func SetupHandler() {
var myApi PetStoreImpl // This implements the pet store interface
e := echo.New()
petstore.RegisterHandlers(e, &myApi)
...
}
Chi
Code generated using -generate chi-server
.
type PetStoreImpl struct {}
func (*PetStoreImpl) GetPets(w http.ResponseWriter, r *http.Request) {
// Implement me
}
func SetupHandler() {
var myApi PetStoreImpl
r := chi.NewRouter()
r.Mount("/", Handler(&myApi))
}
Gin
Code generated using -generate gin
.
The usage of gin
is out of scope of this doc, but once you have an gin instance, we generate a utility function to help you associate your handlers with this autogenerated code. For the pet store, it looks like this:
// RegisterHandlersWithOptions creates http.Handler with additional options
func RegisterHandlersWithOptions(router *gin.Engine, si ServerInterface, options GinServerOptions) *gin.Engine {
wrapper := ServerInterfaceWrapper{
Handler: si,
HandlerMiddlewares: options.Middlewares,
}
router.GET(options.BaseURL+"/pets", wrapper.FindPets)
router.POST(options.BaseURL+"/pets", wrapper.AddPet)
router.DELETE(options.BaseURL+"/pets/:id", wrapper.DeletePet)
router.GET(options.BaseURL+"/pets/:id", wrapper.FindPetByID)
return router
}
import (
"github.com/gin-gonic/gin"
"github.com/deepmap/oapi-codegen/examples/petstore-expanded/gin/api"
middleware "github.com/deepmap/oapi-codegen/pkg/gin-middleware"
)
type PetStoreImpl struct {}
func (*PetStoreImpl) GetPets(w http.ResponseWriter, r *http.Request) {
// Implement me
}
func SetupHandler() {
var myApi PetStoreImpl
r := gin.Default()
r.Use(middleware.OapiRequestValidator(swagger))
r = api.RegisterHandlers(r, petStore)
}
net/http
Chi is 100% compatible with net/http
allowing the following with code generated using -generate chi-server
.
type PetStoreImpl struct {}
func (*PetStoreImpl) GetPets(w http.ResponseWriter, r *http.Request) {
// Implement me
}
func SetupHandler() {
var myApi PetStoreImpl
http.Handle("/", Handler(&myApi))
}
Alternatively, Gorilla is also 100% compatible with net/http
and can be generated with -generate gorilla
.
oapi-codegen also supports generating RPC inspired strict server, that will parse request bodies and encode responses. The main points of this code is to automate some parsing, abstract user code from server specific code, and also to force user code to comply with the schema. It supports binding of application/json
and application/x-www-form-urlencoded
to a struct, for multipart
requests it generates a multipart.Reader
, which can be used to either manually iterating over parts or using runtime.BindMultipart
function to bind the form to a struct. All other content types are represented by a io.Reader
interface.
To form a response simply return one of the generated structs with corresponding status code and content type. For example, to return a status code 200 JSON response for a AddPet use the AddPet200JSONResponse
struct which will set the correct Content-Type header, status code and will marshal the response data. You can also return an error, that will cause an Internal Server Error
response.
Short example:
type PetStoreImpl struct {}
func (*PetStoreImpl) GetPets(ctx context.Context, request GetPetsRequestObject) (GetPetsResponseObject, error) {
var result []Pet
// Implement me
return GetPets200JSONResponse(result), nil
}
For a complete example see /examples/petstore-expanded/strict
.
Code is generated with a configuration flag generate: strict-server: true
along with any other server (echo, chi, gin and gorilla are supported). The generated strict wrapper can then be used as an implementation for ServerInterface
. Setup example:
func SetupHandler() {
var myApi PetStoreImpl
myStrictApiHandler := api.NewStrictHandler(myApi, nil)
e := echo.New()
petstore.RegisterHandlers(e, &myStrictApiHandler)
}
Strict server also has its own middlewares. It can access to both request and response structs, as well as raw request\response data. It can be used for logging the parsed request\response objects, transforming go errors into response structs, authorization, etc. Note that middlewares are server-specific.
OpenAPI Schemas implicitly accept additionalProperties
, meaning that any fields provided, but not explicitly defined via properties on the schema are accepted as input, and propagated. When unspecified, the additionalProperties
field is assumed to be true
.
Additional properties are tricky to support in Go with typing, and require lots of boilerplate code, so in this library, we assume that additionalProperties
defaults to false
and we don't generate this boilerplate. If you would like an object to accept additionalProperties
, specify a schema for additionalProperties
.
Say we declared NewPet
above like so:
NewPet:
required:
- name
properties:
name:
type: string
tag:
type: string
additionalProperties:
type: string
The Go code for NewPet
would now look like this:
// NewPet defines model for NewPet.
type NewPet struct {
Name string `json:"name"`
Tag *string `json:"tag,omitempty"`
AdditionalProperties map[string]string `json:"-"`
}
The additionalProperties, of type string
become map[string]string
, which maps field names to instances of the additionalProperties
schema.
// Getter for additional properties for NewPet. Returns the specified
// element and whether it was found
func (a NewPet) Get(fieldName string) (value string, found bool) {...}
// Setter for additional properties for NewPet
func (a *NewPet) Set(fieldName string, value string) {...}
// Override default JSON handling for NewPet to handle additionalProperties
func (a *NewPet) UnmarshalJSON(b []byte) error {...}
// Override default JSON handling for NewPet to handle additionalProperties
func (a NewPet) MarshalJSON() ([]byte, error) {...}w
There are many special cases for additionalProperties
, such as having to define types for inner fields which themselves support additionalProperties, and all of them are tested via the internal/test/components
schemas and tests. Please look through those tests for more usage examples.
oneOf
and anyOf
are implemented using delayed parsing with the help of json.RawMessage
. The following schema will result in a type that has methods such as AsCat
, AsDog
, FromCat
, FromDog
, MergeCat
, MergeDog
. If the schema also includes a discriminator the generated code will also have methods such as Discriminator
, ValueByDiscriminator
and will force discriminator value in From
methods.schema:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
allOf
is supported, by taking the union of all the fields in all the component schemas. This is the most useful of these operations, and is commonly used to merge objects with an identifier, as in the petstore-expanded
example.Once your server is up and running, you probably want to make requests to it. If you're going to do those requests from your Go code, we also generate a client which is conformant with your schema to help in marshaling objects to JSON. It uses the same types and similar function signatures to your request handlers.
The interface for the pet store looks like this:
// The interface specification for the client above.
type ClientInterface interface {
// FindPets request
FindPets(ctx context.Context, params *FindPetsParams, reqEditors ...RequestEditorFn) (*http.Response, error)
// AddPet request with JSON body
AddPet(ctx context.Context, body NewPet, reqEditors ...RequestEditorFn) (*http.Response, error)
// DeletePet request
DeletePet(ctx context.Context, id int64, reqEditors ...RequestEditorFn) (*http.Response, error)
// FindPetById request
FindPetById(ctx context.Context, id int64, reqEditors ...RequestEditorFn) (*http.Response, error)
}
A Client object which implements the above interface is also generated:
// Client which conforms to the OpenAPI3 specification for this service.
type Client struct {
// The endpoint of the server conforming to this interface, with scheme,
// https://api.deepmap.com for example.
Server string
// HTTP client with any customized settings, such as certificate chains.
Client http.Client
// A callback for modifying requests which are generated before sending over
// the network.
RequestEditors []func(ctx context.Context, req *http.Request) error
}
Each operation in your OpenAPI spec will result in a client function which takes the same arguments. It's difficult to handle any arbitrary body that Swagger supports, so we've done some special casing for bodies, and you may get more than one function for an operation with a request body.
If you have more than one request body type, meaning more than one media type, you will have a generic handler of this form:
AddPet(ctx context.Context, contentType string, body io.Reader)
If you have only a JSON request body, you will get:
AddPet(ctx context.Context, body NewPet)
If you have multiple request body types, which include a JSON type you will get two functions. We've chosen to give the JSON version a shorter name, as we work with JSON and don't want to wear out our keyboards.
AddPet(ctx context.Context, body NewPet)
AddPetWithBody(ctx context.Context, contentType string, body io.Reader)
The Client object above is fairly flexible, since you can pass in your own http.Client
and a request editing callback. You can use that callback to add headers. In our middleware stack, we annotate the context with additional information such as the request ID and function tracing information, and we use the callback to propagate that information into the request headers. Still, we can't foresee all possible usages, so those functions call through to helper functions which create requests. In the case of the pet store, we have:
// Request generator for FindPets
func NewFindPetsRequest(server string, params *FindPetsParams) (*http.Request, error) {...}
// Request generator for AddPet with JSON body
func NewAddPetRequest(server string, body NewPet) (*http.Request, error) {...}
// Request generator for AddPet with non-JSON body
func NewAddPetRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) {...}
// Request generator for DeletePet
func NewDeletePetRequest(server string, id int64) (*http.Request, error) {...}
// Request generator for FindPetById
func NewFindPetByIdRequest(server string, id int64) (*http.Request, error) {...}
You can call these functions to build an http.Request
from Go objects, which will correspond to your request schema. They map one-to-one to the functions on the client, except that we always generate the generic non-JSON body handler.
There are some caveats to using this code.
exploded, form style query arguments, which are the default argument format in OpenAPI 3.0 are undecidable. Say that I have two objects, one composed of the fields (name=bob, id=5)
and another which has (name=shoe, color=brown)
. The first parameter is named person
and the second is named item
. The default marshaling style for query args would result in /path/?name=bob,id=5&name=shoe,color=brown
. In order to tell what belongs to which object, we'd have to look at all the parameters and try to deduce it, but we're lazy, so we didn't. Don't use exploded form style arguments if you're passing around objects which have similar field names. If you used unexploded form parameters, you'd have /path/?person=name,bob,id,5&item=name,shoe,color,brown
, which an be parsed unambiguously.
Parameters can be defined via schema
or via content
. Use the content
form for anything other than trivial objects, they can marshal to arbitrary JSON structures. When you send them as cookie (in: cookie
) arguments, we will URL encode them, since JSON delimiters aren't allowed in cookies.
If you generate client-code, you can use some default-provided security providers which help you to use the various OpenAPI 3 Authentication mechanism.
import (
"github.com/deepmap/oapi-codegen/pkg/securityprovider"
)
func CreateSampleProviders() error {
// Example BasicAuth
// See: https://swagger.io/docs/specification/authentication/basic-authentication/
basicAuthProvider, basicAuthProviderErr := securityprovider.NewSecurityProviderBasicAuth("MY_USER", "MY_PASS")
if basicAuthProviderErr != nil {
panic(basicAuthProviderErr)
}
// Example BearerToken
// See: https://swagger.io/docs/specification/authentication/bearer-authentication/
bearerTokenProvider, bearerTokenProviderErr := securityprovider.NewSecurityProviderBearerToken("MY_TOKEN")
if bearerTokenProviderErr != nil {
panic(bearerTokenProviderErr)
}
// Example ApiKey provider
// See: https://swagger.io/docs/specification/authentication/api-keys/
apiKeyProvider, apiKeyProviderErr := securityprovider.NewSecurityProviderApiKey("query", "myApiKeyParam", "MY_API_KEY")
if apiKeyProviderErr != nil {
panic(apiKeyProviderErr)
}
// Example providing your own provider using an anonymous function wrapping in the
// InterceptoFn adapter. The behaviour between the InterceptorFn and the Interceptor interface
// are the same as http.HandlerFunc and http.Handler.
customProvider := func(req *http.Request, ctx context.Context) error {
// Just log the request header, nothing else.
log.Println(req.Header)
return nil
}
// Exhaustive list of some defaults you can use to initialize a Client.
// If you need to override the underlying httpClient, you can use the option
//
// WithHTTPClient(httpClient *http.Client)
//
client, clientErr := NewClient("https://api.deepmap.com", WithRequestEditorFn(apiKeyProvider.Intercept))
return nil
}
oapi-codegen
supports the following extended properties:
x-go-type
: specifies Go type name. It allows you to specify the type name for a schema, and will override any default value. This extended property isn't supported in all parts of OpenAPI, so please refer to the spec as to where it's allowed. Swagger validation tools will flag incorrect usage of this property.
x-go-name
: specifies Go field name. It allows you to specify the field name for a schema, and will override any default value. This extended property isn't supported in all parts of OpenAPI, so please refer to the spec as to where it's allowed. Swagger validation tools will flag incorrect usage of this property.
x-go-json-ignore
: sets tag to -
to ignore the field in json completely.
x-oapi-codegen-extra-tags
: adds extra Go field tags to the generated struct field. This is useful for interfacing with tag based ORM or validation libraries. The extra tags that are added are in addition to the regular json tags that are generated. If you specify your own json
tag, you will override the default one.
In the example above, field name
will be declared as:
Name string `json:"name" tag1:"value1" tag2:"value2"`
components:
schemas:
Object:
properties:
name:
type: string
x-oapi-codegen-extra-tags:
tag1: value1
tag2: value2
x-go-type-import
: adds extra Go imports to your generated code. It can help you, when you want to choose your own import package for x-go-type
.
After code generation you will get this:
name
is an optional parameter. Example:
After code generation you will get this result:
import (
"github.com/google/uuid"
)
// Pet defines model for Pet.
type Pet struct {
Age uuid.UUID `json:"age"`
}
components:
schemas:
Pet:
properties:
age:
x-go-type: uuid.UUID
x-go-type-import:
path: github.com/google/uuid
required:
- age
import (
...
myuuid "github.com/google/uuid"
)
//Pet defines model for Pet.
type Pet struct {
Age *myuuid.UUID `json:"age,omitempty"`
}
schemas:
Pet:
properties:
age:
x-go-type: myuuid.UUID
x-go-type-import:
name: myuuid
path: github.com/google/uuid
x-enum-varnames
: supplies other enum names for the corresponding values. (alias: x-enumNames
)
After code generation you will get this result:
// Defines values for ObjectCategory.
const (
Notice ObjectCategory = 0
Urgent ObjectCategory = 2
Warning ObjectCategory = 1
)
// ObjectCategory defines model for Object.Category.
type ObjectCategory int
components:
schemas:
Object:
properties:
category:
type: integer
enum: [0, 1, 2]
x-enum-varnames:
- notice
- warning
- urgent
oapi-codegen
The default options for oapi-codegen
will generate everything; client, server, type definitions and embedded swagger spec, but you can generate subsets of those via the -generate
flag. It defaults to types,client,server,spec
, but you can specify any combination of those.
types
: generate all type definitions for all types in the OpenAPI spec. This will be everything under #components
, as well as request parameter, request body, and response type objects.server
: generate the Echo server boilerplate. server
requires the types in the same package to compile.chi-server
: generate the Chi server boilerplate. This code is dependent on that produced by the types
target.client
: generate the client boilerplate. It, too, requires the types to be present in its package.spec
: embed the OpenAPI spec into the generated code as a gzipped blob. This is then usable with the OapiRequestValidator
, or to be used by other methods that need access to the parsed OpenAPI specificationskip-fmt
: skip running goimports
on the generated code. This is useful for debugging the generated file in case the spec contains weird strings.skip-prune
: skip pruning unused components from the spec prior to generating the code.import-mapping
: specifies a map of references external OpenAPI specs to go Go include paths. Please see below.So, for example, if you would like to produce only the server code, you could run oapi-codegen -generate types,server
. You could generate types
and server
into separate files, but both are required for the server code.
oapi-codegen
can filter paths base on their tags in the openapi definition. Use either -include-tags
or -exclude-tags
followed by a comma-separated list of tags. For instance, to generate a server that serves all paths except those tagged with auth
or admin
, use the argument, -exclude-tags="auth,admin"
. To generate a server that only handles admin
paths, use the argument -include-tags="admin"
. When neither of these arguments is present, all paths are generated.
oapi-codegen
can filter schemas based on the option --exclude-schemas
, which is a comma separated list of schema names. For instance, --exclude-schemas=Pet,NewPet
will exclude from generation schemas Pet
and NewPet
. This allow to have a in the same package a manually defined structure or interface and refer to it in the openapi spec.
Since go generate
commands must be a single line, all the options above can make them pretty unwieldy, so you can specify all of the options in a configuration file via the --config
option. Please see the test under /internal/test/externalref/
for an example. The structure of the file is as follows:
package: externalref
generate:
models: true
embedded-spec: true
import-mapping:
./packageA/spec.yaml: github.com/deepmap/oapi-codegen/internal/test/externalref/packageA
./packageB/spec.yaml: github.com/deepmap/oapi-codegen/internal/test/externalref/packageB
output: externalref.gen.go
output-options:
skip-prune: true
Have a look at cmd/oapi-codegen/oapi-codegen.go
to see all the fields on the configuration structure.
OpenAPI specifications may contain references to other OpenAPI specifications, and we need some additional information in order to be able to generate correct Go code.
An external reference looks like this:
$ref: ./some_spec.yaml#/components/schemas/Type
We assume that you have already generated the boilerplate code for ./some_spec.yaml
using oapi-codegen
, and you have a package which contains the generated code, let's call it github.com/deepmap/some-package
. You need to tell oapi-codegen
that some_spec.yaml
corresponds to this package, and you would do it by specifying this command line argument:
-import-mapping=./some_spec.yaml:github.com/deepmap/some-package
This tells us that in order to resolve references generated from some_spec.yaml
we need to import github.com/deepmap/some-package
. You may specify multiple mappings by comma separating them in the form key1:value1,key2:value2
.
This code is still young, and not complete, since we're filling it in as we need it. We've not yet implemented several things:
patternProperties
isn't yet supported and will exit with an error. Pattern properties were defined in JSONSchema, and the kin-openapi
Swagger object knows how to parse them, but they're not part of OpenAPI 3.0, so we've left them out, as support is very complicated.The code generator uses a tool to inline all the template definitions into code, so that we don't have to deal with the location of the template files. When you update any of the files under the templates/
directory, you will need to regenerate the template inlines:
go generate ./pkg/codegen/templates
All this command does is inline the files ending in .tmpl
into the specified Go file.
Afterwards you should run go generate ./...
, and the templates will be updated accordingly.
Alternatively, you can provide custom templates to override built-in ones using the -templates
flag specifying a path to a directory containing templates files. These files must be named identically to built-in template files (see pkg/codegen/templates/*.tmpl
in the source code), and will be interpreted on-the-fly at run time. Example:
$ ls -1 my-templates/
client.tmpl
typedef.tmpl
$ oapi-codegen \
-templates my-templates/ \
-generate types,client \
petstore-expanded.yaml
Author: Deepmap
Source Code: https://github.com/deepmap/oapi-codegen
License: Apache-2.0 license
1665562500
An example of gin contains many useful features
$ go get github.com/EDDYCJY/go-gin-example
Create a blog database and import SQL
You should modify conf/app.ini
[database]
Type = mysql
User = root
Password =
Host = 127.0.0.1:3306
Name = blog
TablePrefix = blog_
[redis]
Host = 127.0.0.1:6379
Password =
MaxIdle = 30
MaxActive = 30
IdleTimeout = 200
...
$ cd $GOPATH/src/go-gin-example
$ go run main.go
Project information and existing API
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET /auth --> github.com/EDDYCJY/go-gin-example/routers/api.GetAuth (3 handlers)
[GIN-debug] GET /swagger/*any --> github.com/EDDYCJY/go-gin-example/vendor/github.com/swaggo/gin-swagger.WrapHandler.func1 (3 handlers)
[GIN-debug] GET /api/v1/tags --> github.com/EDDYCJY/go-gin-example/routers/api/v1.GetTags (4 handlers)
[GIN-debug] POST /api/v1/tags --> github.com/EDDYCJY/go-gin-example/routers/api/v1.AddTag (4 handlers)
[GIN-debug] PUT /api/v1/tags/:id --> github.com/EDDYCJY/go-gin-example/routers/api/v1.EditTag (4 handlers)
[GIN-debug] DELETE /api/v1/tags/:id --> github.com/EDDYCJY/go-gin-example/routers/api/v1.DeleteTag (4 handlers)
[GIN-debug] GET /api/v1/articles --> github.com/EDDYCJY/go-gin-example/routers/api/v1.GetArticles (4 handlers)
[GIN-debug] GET /api/v1/articles/:id --> github.com/EDDYCJY/go-gin-example/routers/api/v1.GetArticle (4 handlers)
[GIN-debug] POST /api/v1/articles --> github.com/EDDYCJY/go-gin-example/routers/api/v1.AddArticle (4 handlers)
[GIN-debug] PUT /api/v1/articles/:id --> github.com/EDDYCJY/go-gin-example/routers/api/v1.EditArticle (4 handlers)
[GIN-debug] DELETE /api/v1/articles/:id --> github.com/EDDYCJY/go-gin-example/routers/api/v1.DeleteArticle (4 handlers)
Listening port is 8000
Actual pid is 4393
Swagger doc
Author: Eddycjy
Source Code: https://github.com/eddycjy/go-gin-example
License: MIT license
1662871030
This tutorial we will discuss on how you can use a Swagger file to design your APIs. We deploy the swagger in AWS API gateway and integrate lambda function with API Gateway. Finally we make an API call to trigger the lambda function.
`npm install -D serverless-auto-swagger`
Swagger is a suite of tools for API developers from SmartBear Software and a former specification upon which the OpenAPI Specification is based.
Amazon API Gateway is a fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure APIs at any scale. APIs act as the "front door" for applications to access data, business logic, or functionality from your backend services. Using API Gateway, you can create RESTful APIs and WebSocket APIs that enable real-time two-way communication applications. API Gateway supports containerized and serverless workloads, as well as web applications.
API Gateway handles all the tasks involved in accepting and processing up to hundreds of thousands of concurrent API calls, including traffic management, CORS support, authorization and access control, throttling, monitoring, and API version management. API Gateway has no minimum fees or startup costs. You pay for the API calls you receive and the amount of data transferred out and, with the API Gateway tiered pricing model, you can reduce your cost as your API usage scales.
AWS Lambda is an event-driven, serverless computing platform provided by Amazon as a part of Amazon Web Services. It is a computing service that runs code in response to events and automatically manages the computing resources required by that code.
Subscribe: https://www.youtube.com/c/CloudGurus/featured
#apigateway #awslambda #swagger
1660446240
This library reads your JSDoc-annotated source code and generates an OpenAPI (Swagger) specification.
Imagine having API files like these:
/**
* @openapi
* /:
* get:
* description: Welcome to swagger-jsdoc!
* responses:
* 200:
* description: Returns a mysterious string.
*/
app.get('/', (req, res) => {
res.send('Hello World!');
});
The library will take the contents of @openapi
(or @swagger
) with the following configuration:
const swaggerJsdoc = require('swagger-jsdoc');
const options = {
definition: {
openapi: '3.0.0',
info: {
title: 'Hello World',
version: '1.0.0',
},
},
apis: ['./src/routes*.js'], // files containing annotations as above
};
const openapiSpecification = swaggerJsdoc(options);
The resulting openapiSpecification
will be a swagger tools-compatible (and validated) specification.
You are viewing swagger-jsdoc
v6 which is published in CommonJS module system.
npm install swagger-jsdoc --save
Or
yarn add swagger-jsdoc
By default swagger-jsdoc
tries to parse all docs to it's best capabilities. If you'd like to you can instruct an Error to be thrown instead if validation failed by setting the options flag failOnErrors
to true
. This is for instance useful if you want to verify that your swagger docs validate using a unit test.
const swaggerJsdoc = require('swagger-jsdoc');
const options = {
failOnErrors: true, // Whether or not to throw when parsing errors. Defaults to false.
definition: {
openapi: '3.0.0',
info: {
title: 'Hello World',
version: '1.0.0',
},
},
apis: ['./src/routes*.js'],
};
const openapiSpecification = swaggerJsdoc(options);
Click on the version you are using for further details:
Author: Surnet
Source Code: https://github.com/Surnet/swagger-jsdoc
License: MIT license
1660359300
Run this command:
With Flutter:
$ flutter pub add fact_schemas
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
fact_schemas: ^1.0.5
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:fact_schemas/fact_schemas.dart';
Original article source at: https://pub.dev/packages/fact_schemas
1659834540
A complete user registry, with access permissions, JWT token, integration and unit tests, using the RESTful API pattern.
^13
^17
^3.8.4
This project was started with Spring Initializr.
# clone the repository and access the directory.
$ git clone git@github.com:Throyer/springboot-api-crud.git && cd springboot-api-crud
# download dependencies
$ mvn install -DskipTests
# run the application
$ mvn spring-boot:run
# run the tests
$ mvn test
# to build for production
$ mvn clean package
# to generate the coverage report after testing (available at: target/site/jacoco/index.html)
$ mvn jacoco:report
use the parameter -Dtest=<class>#<method>
for example the integration test. creating a user:
$ mvn test -Dtest=UsersControllerIntegrationTests#should_save_a_new_user
Once the application is up, it is available at: localhost:8080/documentation
Creating database migration files
🚨 make sure you have maven in your environment and that you are in the correct directory ./api
Java based migrations
mvn migration:generate -Dname=my-migration-name
SQL based migrations
mvn migration:generate -Dname=my-migration-name -Dsql
🚨 create
environment
filecp docker/.env.example docker/.env
docker compose development
docker-compose -p example-api-development -f ./docker/docker-compose.dev.yml --env-file ./docker/.env up -d --force-recreate
docker compose production
docker-compose -p example-api -f ./docker/docker-compose.prod.yml --env-file ./docker/.env up -d --build
or
# development up / down
scripts/dev.sh up
scripts/dev.sh down
# production up / down
scripts/prod.sh up
scripts/prod.sh down
Description | Parameter | Default values |
---|---|---|
server port | SERVER_PORT | 8080 |
database url | DB_URL | localhost:5432/common_app |
username (database) | DB_USERNAME | root |
user password (database) | DB_PASSWORD | root |
displays the generated sql in the logger | DB_SHOW_SQL | false |
set maximum database connections | DB_MAX_CONNECTIONS | 5 |
secret value in token generation | TOKEN_SECRET | secret |
token expiration time in hours | TOKEN_EXPIRATION_IN_HOURS | 24 |
refresh token expiry time in days | REFRESH_TOKEN_EXPIRATION_IN_DAYS | 7 |
SMTP server address | SMTP_HOST | smtp.gmail.com |
SMTP server port | SMTP_PORT | 587 |
SMTP username | SMTP_USERNAME | user |
SMTP server password | SMTP_PASSWORD | secret |
time for recovery email to expire | MINUTES_TO_EXPIRE_RECOVERY_CODE | 20 |
max requests per minute | MAX_REQUESTS_PER_MINUTE | 10 |
swagger username | SWAGGER_USERNAME | null |
swagger password | SWAGGER_PASSWORD | null |
these variables are defined in: application.properties
# to change the value of some environment variable at runtime # on execution, just pass it as a parameter. (like --SERVER_PORT=80). $ java -jar api-4.1.2.jar --SERVER_PORT=80
Author: Throyer
Source code: https://github.com/Throyer/springboot-api-rest-example
License: GPL-3.0 license
#spring #springboot #java #restapi #jwt #swagger
1657249268
Automatically generate OpenApi, Swagger, and Redoc documentation from your existing CakePHP code
Check out the demo applications for examples.
This is built for CakePHP 4.x only. Supported versions:
Version | Branch | Cake Version | PHP Version |
---|---|---|---|
2.* | master | ^4.2 | 8.0+ |
1.* | 1.next | ^4.0 | 7.2+ |
SwaggerBake requires CakePHP4 and a few dependencies that will be automatically installed via composer.
composer require cnizzardini/cakephp-swagger-bake
Run bin/cake plugin load SwaggerBake
or manually load the plugin:
# src/Application.php
public function bootstrap(): void
{
// other logic...
$this->addPlugin('SwaggerBake');
}
For standard applications that have not split their API into plugins, the automated setup should work. Otherwise use the manual setup.
Run the installer:
bin/cake swagger install
Then load the config and add a route.
Create a base swagger.yml file at config\swagger.yml
. An example file is provided here.
Create a swagger_bake.php config file at config/swagger_bake.php
file. See the example file here for further explanation. Then just add a route.
For more read sections on Multiple Instances of SwaggerBake and Extending Views and Controllers
In your config/bootstrap.php
file:
Configure::load('swagger_bake', 'default', false);
Create a route for the SwaggerUI page in config/routes.php
, example:
$builder->connect(
'/api',
['plugin' => 'SwaggerBake', 'controller' => 'Swagger', 'action' => 'index']
);
You can now browse to either /api
for swagger or /api?doctype=redoc
for redoc. Your OpenAPI JSON will exist at /api/swagger.json
.
bin/cake swagger bake
If Hot Reload is enabled (see config) OpenAPI will be generated each time you browse to SwaggerUI (or Redoc) in your web browser.
You can also generate OpenAPI programmatically:
$swagger = (new \SwaggerBake\Lib\SwaggerFactory())->create();
$swagger->getArray(); # returns swagger array
$swagger->toString(); # returns swagger json
$swagger->writeFile('/full/path/to/your/swagger.json'); # writes swagger.json
Your RESTful routes are used to build OpenAPI paths and operations.
SwaggerBake will parse the DocBlocks on your controller actions for additional OpenAPI data.
/**
* OpenAPI Operation Summary
*
* This displays as the operations long description
*
* @link https://book.cakephp.org/4/en/index.html External documentation
* @deprecated Indicates the operation is deprecated
* @throws \Cake\Http\Exception\BadRequestException Appears as 400 response with this description
* @throws \Exception Appears as 500 response with this description
*/
public function index() {}
If you prefer, you may use the OpenApiOperation, OpenApiResponse attributes instead. These attributes take precedence over doc block parsing. Read below for a full list of attributes.
OpenAPI schema is built from your Table and Entity classes and any validators you've defined in them. You may adjust the default schema using the OpenApiSchema and OpenApiSchemaProperty attributes.
For additional functionality the following PHP8 Attributes may be used. These can be imported individually from the SwaggerBake\Lib\Attribute
namespace. Read the Attributes docs for detailed examples. If you are using version 1 you will need to use annotations.
Attribute | Usage | Description |
---|---|---|
OpenApiDto | Controller Action | Builds OpenAPI query params and request bodies from Data Transfer Objects |
OpenApiForm | Controller Action | Builds OpenAPI for application/x-www-form-urlencoded request bodies |
OpenApiHeader | Controller Action | Create OpenAPI header parameters |
OpenApiOperation | Controller Action | Modifies OpenAPI operation |
OpenApiPaginator | Controller Action | Create OpenAPI query params from CakePHP Paginator Component |
OpenApiPath | Controller | Modifies OpenAPI paths |
OpenApiPathParam | Controller Action | Modify an existing OpenAPI path parameter |
OpenApiQueryParam | Controller Action | Builds OpenAPI query param |
OpenApiRequestBody | Controller Action | Modify OpenAPI request body |
OpenApiResponse | Controller Action | Modify OpenAPI response |
OpenApiSchema | Entity | Modifies OpenAPI schema |
OpenApiSchemaProperty | Entity or Class | Modifies an OpenAPI schema property or defines OpenApiResponse schema |
OpenApiSearch | Controller Action | Create OpenAPI query params from CakePHP Search plugin |
OpenApiSecurity | Controller Action | Create/modify OpenAPI security |
DTO class property | Builds OpenAPI query param from Data Transfer Objects (deprecated, use OpenApiQueryParam in v2.2.5+) | |
DTO class property | Builds OpenAPI request body property from Data Transfer Objects (deprecated, use OpenApiSchemaProperty in v2.2.5+) |
SwaggerBake comes with an event system to allow for further control over your OpenAPI schema.
Event | Description |
---|---|
SwaggerBake.Operation.created | Dispatched each time an OpenAPI Path > Operation is created |
SwaggerBake.Path.created | Dispatched each time an OpenAPI Path is created |
SwaggerBake.Schema.created | Dispatched each time an OpenAPI Schema is created |
SwaggerBake.initialize | Dispatched during initialization phase on SwaggerBake |
SwaggerBake.beforeRender | Dispatched before SwaggerBake outputs OpenAPI JSON |
By default, SwaggerBake uses '#/components/schemas/Exception'
as your OpenAPI documentations Exception schema. See the default swagger.yml and exceptionSchema
in swagger_bake.php for more info. You can further customize with attributes and @throws
.
Using the ref
or schema
properties of OpenApiResponse.
@throws
tag and OpenApiExceptionSchemaInterfaceImplement SwaggerBake\Lib\OpenApiExceptionSchemaInterface
on your exception class, then document the exception with a @throws
tag in your controller action's doc block.
/**
* @throws \App\Exception\MyException
*/
public function add(){}
Example exception class:
class MyException implements OpenApiExceptionSchemaInterface
{
public static function getExceptionCode(): string
{
return '400';
}
public static function getExceptionDescription(): ?string
{
return 'An optional description'; // returning null omits the response description
}
public static function getExceptionSchema(): Schema|string
{
return (new \SwaggerBake\Lib\OpenApi\Schema())
->setTitle('MyException')
->setProperties([
(new SchemaProperty())->setType('string')->setName('code')->setExample('400'),
(new SchemaProperty())->setType('string')->setName('message')->setExample('error'),
(new SchemaProperty())->setType('string')->setName('wherever')->setExample('whatever you want')
]);
}
}
It's possible to write extensions for SwaggerBake. Read the extensions documentation. There are several other options to extend functionality documented below:
You may use your own swagger or redoc install in lieu of the version that comes with SwaggerBake. Simply don't add a custom route as indicated in the installation steps. In this case just reference the generated swagger.json within your userland Swagger UI install.
You might want to perform some additional logic (checking for authentication) before rendering the built-in Swagger UI. This is easy to do. Just create your own route and controller, then reference the built-in layout and template:
// config/routes.php
$builder->connect('/my-swagger-docs', ['controller' => 'MySwagger', 'action' => 'index']);
To get started, copy SwaggerController into your project.
Note: SwaggerUiComponent has been deprecated in version 2.3.0 and will be removed in version 3.
You will need to use your own controller (see above). From there you can copy the layouts and templates into your project and inform your controller action to use them instead. Checkout out the CakePHP documentation on Views for specifics. This can be useful if you'd like to add additional functionality to SwaggerUI (or Redoc) using their APIs or if your project is not installed in your web servers document root (i.e. a sub-folder).
If your application has multiple APIs that are split into plugins you can generate unique OpenAPI schema, Swagger UI, and Redoc for each plugin. Setup a new swagger_bake.php
and swagger.yaml
in plugins/OtherApi/config
. These configurations should point to your plugins paths and namespaces. Next, create a custom SwaggerController and load the configuration within initialize()
:
public function initialize(): void
{
parent::initialize();
Configure::load('OtherApi.swagger_bake', 'default', false); // note: `false` for the third argument is important
/*
* Only load the component if you are using a version older than v2.3.0. This component will be deprecated
* in v3.0.0
*/
$this->loadComponent('SwaggerBake.SwaggerUi');
}
When running bin/cake swagger bake
you will need to specify your plugins swagger_bake config:
bin/cake swagger bake --config OtherApi.swagger_bake
In addition to swagger bake
these console helpers provide insight into how your Swagger documentation is generated.
swagger routes
Displays a list of routes that can be viewed in Swagger.
bin/cake swagger routes
swagger models
Displays a list of models that can be viewed in Swagger.
bin/cake swagger models
SwaggerBake comes with Bake templates for scaffolding RESTful controllers compatible with SwaggerBake and OpenAPI 3.0 schema. Using the bake theme is completely optional, but will save you some time since the default bake theme is not specifically designed for RESTful APIs.
bin/cake bake controller {Name} --theme SwaggerBake
No API definition provided.
Verify that swagger.json exists.
Unable to create swagger file. Try creating an empty file first or checking permissions
Create the swagger.json manually matching the path in your config/swagger_bake.php
file.
Output file is not writable
Change permissions on your swagger.json file
, 764
should do.
Controller not found
Make sure a controller actually exists for the route resource.
Make sure yours route are properly defined in config/routes.php
per the CakePHP RESTful routing documentation.
Sample schema is determined using CakePHP naming conventions. Does your controller name match your model names? For customizing response schema see OpenApiResponse.
Sample schema is determined using CakePHP naming conventions. Does your controller name match your model names? For customizing request schema see OpenApiRequestBody.
Either disable CSRF protection on your main route in config/routes.php
or enable CSRF protection in Swagger UI. The library does not currently support adding this in for you.
Swagger UI sends HTTP DELETE without an accept
header. If the record does not exist, an exception is generated. This results in an HTML response being generated which can be quite large and cause the UI to be slow to render. To get around this you can force an accept
value on the header using the CakePHP middleware:
# src/Application.php
public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
{
$middlewareQueue
->add(function(ServerRequestInterface $request, RequestHandlerInterface $handler){
$accept = $request->getHeader('accept');
if ($request->getMethod() === 'DELETE' && reset($accept) === '*/*') {
$request = $request->withHeader('accept', 'application/json');
}
return $handler->handle($request);
});
// other middleware...
return $middlewareQueue;
}
Read more about CakePHP middleware in the official documentation.
Send pull requests to help improve this library. You can include SwaggerBake in your primary Cake project as a local source to make developing easier:
Make a fork of this repository and clone it to your localhost
Remove cnizzardini\cakephp-swagger-bake
from your composer.json
Add a paths repository to your composer.json
"minimum-stability": "dev",
"repositories": [
{
"type": "path",
"url": "/absolute/local-path-to/cakephp-swagger-bake",
"options": {
"symlink": true
}
}
]
composer require cnizzardini/cakephp-swagger-bake @dev
Undo these steps when you're done. Read the full composer documentation on loading from path here: https://getcomposer.org/doc/05-repositories.md#path
Check out the extensions documentation to add functionality to this project.
PHPUnit Test Suite:
composer test
PHPUnit, PHPCS, PHPSTAN, and PHPMD:
composer analyze
GrumPHP can be used to run tests and static analyzers in a pre-commit hook.
composer grumphp-init
I've set grumphp to be installed globally: https://github.com/phpro/grumphp/blob/master/doc/installation/global.md
Author: cnizzardini
Source Code: https://github.com/cnizzardini/cakephp-swagger-bake
License: MIT license
1657143600
swagger-php
allows to generate specs either for OpenAPI 3.0.0 or OpenAPI 3.1.0. By default the spec will be in version 3.0.0
. The command line option --version
may be used to change this to 3.1.0
.
Programmatically, the method Generator::setVersion()
can be used to change the version.
swagger-php
requires at least PHP 7.2 for annotations and PHP 8.1 for using attributes.
composer require zircote/swagger-php
For cli usage from anywhere install swagger-php globally and make sure to place the ~/.composer/vendor/bin
directory in your PATH so the openapi
executable can be located by your system.
composer global require zircote/swagger-php
Add annotations to your php files.
/**
* @OA\Info(title="My First API", version="0.1")
*/
/**
* @OA\Get(
* path="/api/resource.json",
* @OA\Response(response="200", description="An example resource")
* )
*/
Visit the Documentation website for the Getting started guide or look at the Examples directory for more examples.
Generate always-up-to-date documentation.
<?php
require("vendor/autoload.php");
$openapi = \OpenApi\Generator::scan(['/path/to/project']);
header('Content-Type: application/x-yaml');
echo $openapi->toYaml();
Documentation of how to use the Generator
class can be found in the Generator reference.
The openapi
command line interface can be used to generate the documentation to a static yaml/json file.
./vendor/bin/openapi --help
Starting with version 4 the default analyser used on the command line is the new ReflectionAnalyser
.
Using the --legacy
flag (-l
) the legacy TokenAnalyser
can still be used.
Generate the OpenApi annotation object from a json string, which makes it easier to manipulate objects programmatically.
<?php
use OpenApi\Serializer;
$serializer = new Serializer();
$openapi = $serializer->deserialize($jsonString, 'OpenApi\Annotations\OpenApi');
echo $openapi->toJson();
Generate the swagger documentation to a static json file.
docker run -v "$PWD":/app -it tico/swagger-php --help
Feel free to submit Github Issues or pull requests.
The documentation website is build from the docs folder with vitepress.
Make sure pull requests pass PHPUnit and PHP-CS-Fixer (PSR-2) tests.
composer test
./bin/phpunit
composer docs:refgen
composer lint
php-cs-fixer
fix linting errors:composer cs
Generate interactive OpenAPI documentation for your RESTful API using doctrine annotations.
For a full list of supported annotations, please have look at the OpenApi\Annotations
namespace or the documentation website.
Author: Zircote
Source Code: https://github.com/zircote/swagger-php
License: Apache-2.0 license
1657136100
CakePHP 4.x plugin that adds auto-generated Swagger 2.0 documentation to your projects using swagger-php and swagger-ui.
Install the plugin using composer:
composer require alt3/cakephp-swagger
Enable the plugin in the bootstrap()
method found in src/Application.php
:
public function bootstrap()
{
parent::bootstrap();
$this->addPlugin('Alt3/Swagger');
}
Also make sure that AssetMiddleware is loaded inside
Application.php
or all Swagger page assets will 404.
After enabling the plugin, browsing to http://your.app/alt3/swagger
should now produce the Swagger-UI interface:
All configuration for this plugin is done through the /config/swagger.php
configuration file. TLDR full example below.
<?php
use Cake\Core\Configure;
return [
'Swagger' => [
'ui' => [
'title' => 'ALT3 Swagger',
'validator' => true,
'api_selector' => true,
'route' => '/swagger/',
'schemes' => ['http', 'https']
],
'docs' => [
'crawl' => Configure::read('debug'),
'route' => '/swagger/docs/',
'cors' => [
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'GET, POST',
'Access-Control-Allow-Headers' => 'X-Requested-With'
]
],
'library' => [
'api' => [
'include' => ROOT . DS . 'src',
'exclude' => [
'/Editor/'
]
],
'editor' => [
'include' => [
ROOT . DS . 'src' . DS . 'Controller' . DS . 'AppController.php',
ROOT . DS . 'src' . DS . 'Controller' . DS . 'Editor',
ROOT . DS . 'src' . DS . 'Model'
]
]
]
]
];
Use the ui
section to customize the following Swagger-UI options:
title
: sets the Swagger-UI page title, defaults to cakephp-swagger
validator
: show/hide the validator image, defaults to true
api_selector
: show/hide the api selector form fields, defaults to true
route
: expose the UI using a custom route, defaults to /alt3/swagger/
schemes
: array used to specify third field used to generate the BASE URL (host
is fetched realtime, basePath
is also fetched realtime if not defined via annotations), defaults to null
Please note that the UI will auto-load the first document found in the library.
Use the docs
section to customize the following options:
crawl
: enable to crawl-generate new documents instead of serving from filesystem, defaults to true
route
: expose the documents using a custom route, defaults to /alt3/swagger/docs/
cors
: specify CORS headers to send with the json responses, defaults to null
Use the library
section to specify one or multiple swagger documents so:
http://your.app/alt3/swagger/docs/:id
(so it can be used by the UI)The following library example would result in:
include
exclude
http://your.app/alt3/swagger/docs/api
http://your.app/alt3/swagger/docs/editor
'library' => [
'api' => [
'include' => ROOT . DS . 'src',
'exclude' => [
'/Editor/'
]
],
'editor' => [
'include' => [
ROOT . DS . 'src' . DS . 'Controller' . DS . 'AppController.php',
ROOT . DS . 'src' . DS . 'Controller' . DS . 'Editor',
ROOT . DS . 'src' . DS . 'Model'
]
]
]
It would also make http://your.app/alt3/swagger/docs
produce a json list with links to all available documents similar to the example below.
{
"success": true,
"data": [
{
"document": "api",
"link": "http://your.app/alt3/swagger/docs/api"
},
{
"document": "editor",
"link": "http://your.app/alt3/swagger/docs/editor"
}
]
}
This plugin comes with a shell that should simplify deployment in production environments. Simply run the following command to create cakephp_swagger
prefixed filesystem documents in tmp/cache
for all entities found in your library.
bin/cake swagger makedocs <host>
The host argument (e.g. your.app.com) is required, should not include protocols and is used to set the
host
property inside your swagger documents.
Explaining swagger-php annotation voodoo is beyond this plugin but to give yourself a head start while creating your first library document you might want to copy/paste the following working example into any of your php files.
Note: the weird non-starred syntax ensures compatibility with the CakePHP Code Sniffer.
<?php
/**
@SWG\Swagger(
@SWG\Info(
title="cakephp-swagger",
description="Quickstart annotation example",
termsOfService="http://swagger.io/terms/",
version="1.0.0"
)
)
@SWG\Get(
path="/cocktails",
summary="Retrieve a list of cocktails",
tags={"cocktail"},
consumes={"application/json"},
produces={"application/json"},
@SWG\Parameter(
name="sort",
description="Sort results by field",
in="query",
required=false,
type="string",
enum={"name", "description"}
),
@SWG\Response(
response="200",
description="Successful operation",
@SWG\Schema(
type="object",
ref="#/definitions/Cocktail"
)
),
@SWG\Response(
response=429,
description="Rate Limit Exceeded"
)
)
@SWG\Definition(
definition="Cocktail",
required={"name", "description"},
@SWG\Property(
property="id",
type="integer",
description="CakePHP record id"
),
@SWG\Property(
property="name",
type="string",
description="CakePHP name field"
),
@SWG\Property(
property="description",
type="string",
description="Description of a most tasty cocktail"
)
)
*/
Which should result in:
Before submitting a PR make sure:
Author: alt3
Source Code: https://github.com/alt3/cakephp-swagger
License: MIT license
1656628740
Swagger is a set of tools around OpenAPI Specification that can help you design, build, document and consume REST APIs.
Binance now offers a YAML collection file on Binance Public Spot API to help developers' consulting of each endpoint through an interactive API documentation via Swagger UI.
/api/*
/sapi/*
There's several options for the approach:
GitHub Pages:
Local UI instance:
./start.sh
3. Open http://localhost:8080
Swagger Inspector:
2. Copy and use previous step's URL in https://inspector.swagger.io/.
IDE (Integrated Development Environment):
Swagger Hub:
Export
section to export as Client SDK, Server Stub or Documentation in multiple languages.Futures and Vanilla Options APIs are not supported:
/fapi/*
/dapi/*
/vapi/*
CORS restrictions: Using Swagger UI beyond as API Documentation consulting, i.e, by actually trying out requests can result in invalid responses for endpoints requiring API Key (requests with header X-MBX-APIKEY
). Swagger Inspector doesn't have this limitation.
No integration of automated generation for dynamic parameters, such as signature
and timestamp
.
Contributions are welcome!
If you've found an issue within this project, please open an issue to discuss what you would like to change.
If it's an issue with the API, please open a topic at our Binance API Community Forum.
Download Details:
Author: binance
Source Code:
License:
#Binance #blockchain #api #swagger
1655982600
Swagger(OpenAPI)は、RESTAPIを記述するための言語に依存しない仕様です。これにより、コンピューターと人間の両方が、ソースコードに直接アクセスしなくてもRESTAPIの機能を理解できます。Swagger UIは、生成されたOpenAPI仕様を使用して、サービスに関する情報を提供するWebベースのUIを提供します。SwaggerUIはPostmanの代替手段です。
私は自分の記事でSwaggerを数回以上使用しましたが、さまざまなトピックで使用されるマイナーなツールとして使用しました。Swaggerの情報を取得しようとしたとき、これらの記事から検索する必要がありましたが、これは便利ではありませんでした。そこで、これら2つの記事、特にSwagger for .NET MVCWebAPIまたは.NETCoreMVCWebAPIについて書き直しました。
新しい.NETCore5.0 Web APIプロジェクトを作成した場合、WebAPI用のSwaggercientがデフォルトでインストールされます。現在のケースでは、.NET Core 5.0を使用していますが、Web APIはMVCモジュールで作成されているため、Swaggerを手動でインストールする必要があります。この方法は、5.0より前の.NETCoreバージョンで機能します。
この記事は、私の別の記事の一部です 。MVCによるWeb APIの使用.NETCore(1)、サーバー、およびフレームワークでは、Swagger関連の部分がここにあります。そこから詳細を見ることができます。
アプリのビルドには、Visual Studio201916.8と.NET5.0SDKのバージョンを使用します。
MVCCallWebAPI
プロジェクト名を入力します。アプリをビルドして実行すると、次の画像にアプリが表示されます。
記事「 .NETCore(1)、サーバーおよびフレームワークでMVCによるWebAPIの消費」を参照してください 。
1.Swaggerクライアントをインストールします
ソリューションエクスプローラー>[NuGetパッケージの管理]でプロジェクトを右クリックし、 Swaggerを検索します
Swashbuckle(Swagger)には3つの主要なコンポーネントがあり、そのうちの2つをインストールするだけで済みます。SwaggerGenとSwaggerUIで、Swaggerが含まれます。
2.startup.cs ファイルにSwaggerクライアントを登録し ます
Startup.ConfigureServices
メソッドのサービスコレクションにSwaggerジェネレーターを追加します 。
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v2", new OpenApiInfo { Title = "MVCCallWebAPI", Version = "v2" });
});
......
}
Startup.Configure
メソッドで、生成されたJSONドキュメントとSwaggerUIを提供するためのミドルウェアを有効にします 。
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v2/swagger.json", "MVCCallWebAPI");
});
......
}
これで、アプリを実行する準備がほぼ整いました。
アプリを実行する前に、ファイルのヘッダーを変更します 。Views/ Shared / _layout.cshtml Viewsを再度変更して、以下に示すSwagger(11〜13行目)を追加します。
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="StoresMVC" asp-action="Index">MVC app</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Swagger" asp-action="Index">Web API</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
次に、アプリを実行します。
Web APIをクリックすると、Swaggerクライアント画面が表示されます。
ソース:https ://www.c-sharpcorner.com/article/swagger-for-net-core-mvc-web-api/
1655949780
Model Generator
This model generator can be used to generate JsonSerializable models
flutter packages run model_generator
By default, the model generator looks for the model yaml file in model_generator/config.yaml
. If you want to overwrite this, specify it in your pubspec.yaml
file by using config_path
. Example of the pubspec.yaml
file if you want to use a custom model file location:
model_generator:
config_path: my_model_dir/config.yaml
You can also specify a command line parameter to override the location for a single run. For this, use the --path
command line parameter. Example:
flutter packages run model_generator --path my_other_model_dir/config.yaml
Example of the pubspec.yaml
file if you want to use a custom base_directory for all your models Default is /lib/model
you can override it for all your models like this:
model_generator:
base_directory: custom_models
this will write all your models to /lib/custom_models path
will be added after the base_directory
If you are using fvm for managing your flutter version. You can add an option to the model generator as well to run with fvm. add an option use_fvm
and set it to true. (by default it is set to false)
model_generator:
use_fvm: true
If you want the generated models to include code for == and hashCode, you can turn it on in pubspec.yaml
. Defaults to false. All fields are taken into consideration for the generated code.
model_generator:
equals_and_hash_code: true
or to override the values per object:
UserModel:
path: webservice/user
equals_and_hash_code: false
properties:
id:
type: int
If you wish to ignore certain fields when generating the ==
and hashCode
methods, you can mark those fields with ignore_equality: true
.
Note: Models with all fields ignored will report a zero hash code and equal only on identity
UserModel:
path: webservice/user
equals_and_hash_code: false
properties:
id:
type: int
ignore_equality: true
include:
type: string
By default json_serializable will not generate the toJson methods on an other json_serializable object or list or map. With the model_generator we can enable this by default since 5.0.0 You can override it at a global level:
model_generator:
explicit_to_json: false
or to override the values per object:
UserModel:
path: webservice/user
explicit_to_json: false
properties:
id:
type: int
If you want the generated models to include generated toString code, you can turn it on in pubspec.yaml
. Defaults to false. All fields are taken into consideration for the generated code.
model_generator:
to_string: true
or to override the values per object:
UserModel:
path: webservice/user
to_string: false
properties:
id:
type: int
If you wish for extra import statements in the generated files and/or extra annotations on the generated model classes, you can specify those in pubspec.yaml
model_generator:
extra_imports:
- 'package:flutter/foundation.dart'
extra_annotations:
- '@immutable'
or to override the values per object:
UserModel:
path: webservice/user
extra_imports:
extra_annotations:
- '@someAnnotation'
properties:
id:
type: int
Since version 5.6.0
default values are supported for properties. You can specify a default value for both required and optional properties by adding default_value: ...
to the property definition.
Note: Default values are taken exactly how they are specified in the yaml file, this means for example that you will need to quote strings correctly, ensure imports are there, ensure the value is a constant, ...
UserModel:
path: webservice/user
extra_imports:
extra_annotations:
- '@someAnnotation'
properties:
id:
type: int
default_value: 1
name:
type: string
required: true
default_value: "'an example quoted string'"
Since version 5.9.0
fields with default values can accept null values in json. In which case the default value will be used instead.
If you wish to control this behaviour, you can add disallow_null_for_defaults: true
to either the model_generator
config or the model property. Alternatively you can specify the behaviour per field by using disallow_null
.
Example:
model_generator:
disallow_null_for_defaults: true
Example 2:
UserModel:
path: webservice/user
disallow_null_for_defaults: true
properties:
id:
type: int
default_value: 1
name:
type: string
required: true
default_value: "'an example quoted string'"
Example 3:
UserModel:
path: webservice/user
properties:
id:
type: int
default_value: 1
name:
type: string
required: true
default_value: "'an example quoted string'"
disallow_null: true
If you want your models to generate code that can be used in combination with generics. use this:
model_generator:
generate_for_generics: true
or to override the default generate_for_generics value in the pubspec.yaml
UserModel:
path: webservice/user
generate_for_generics: true
converters:
- DateTimeConverter
properties:
id:
type: int
If you want your models to expand any other model use extends:
Note: It is not supported to extend custom models
UserDetails:
path: webservice/user
extends: UserModel
properties:
name:
type: string
Example of the model_generator/config.yaml
file
UserModel:
path: webservice/user
converters:
- DateTimeConverter
properties:
id:
type: int
name:
type: string
salary:
type: double
something:
type: dynamic
isLoggedIn:
type: bool
default_value: false
roles:
type: array
items:
type: string
birthday:
type: date
addresses:
type: array
items:
type: Address
idToAddress:
type: map
items:
key: String
value: Address
securityRole:
type: string
jsonKey: securityIndicator
dynamicField:
type: dynamic
includeIfNullField:
include_if_null: false #If this field is null, this field will not be added to your json object (used for PATCH models)
type: string
ignoreField:
ignore: false #this field will not be final, and not be used in the json parsing
type: string
mutableField:
non_final: true #Field will not be marked final
type: string
changedAt:
type: datetime
idToAddressList:
type: map
items:
key: String
value: List<Address>
Address:
path: webservice/user #Can also be package:... and/or end with the actual file (.dart)
properties:
street:
type: string
#Custom base_directory
CustomBaseDirectoryObject:
base_directory: custom_models
path: webservice
properties:
path:
type: string
#Custom json converter. Use with converters property on models
DateTimeConverter:
type: json_converter
path: converter/
Add enums with custom values
Gender:
path: webservice/user
type: enum
properties:
MALE:
value: _mAl3
FEMALE:
value: femAle
X:
value: X
Y:
For enums, it is also possible to have a map generated that maps from the enum value to its string representation and reverse. To enable this, use generate_map: true
Gender:
path: webservice/user
type: enum
generate_map: true
properties:
MALE:
value: _mAl3
FEMALE:
value: femAle
X:
value: X
Y:
When generating maps, it is also possible to specify that special extension functions should be added that return either the string value or that takes a string value and tries to convert it to the enum value. To enable this, use generate_map: true
AND generate_extensions: true
Gender:
path: webservice/user
type: enum
generate_map: true
generate_extensions: true
properties:
MALE:
value: _mAl3
FEMALE:
value: femAle
X:
value: X
Y:
UnknownEnumTestObject:
path: webservice
properties:
path:
unknown_enum_value: X
type: Gender
By default all fields will be converted into uppercase. You can control this behavior globally for all enums or per-enum by setting the uppercase_enums
property to true
( default) or false
model_generator:
uppercase_enums: false
or
UnknownEnumTestObject:
path: webservice
uppercase_enums: false
properties:
path:
Support for custom objects that are not generated by the model generator
CustomObject:
path: data/custom/
type: custom
factory {Model_Name}.fromJson(Map<String, dynamic> json) => _${Model_Name}FromJson(json);
Map<String, dynamic> toJson() => _${Model_Name}ToJson(this);
Support for custom objects but use fromJson & toJson instead of full object parsing:
CustomObjectFromToJson:
path: data/custom/
type: custom_from_to_json
{Model_Name} handle{Model_Name}FromJson(object) => {Model_Name}.fromJson(object);
{Original_Type} handle{Model_Name}ToJson({Model_Name} data) => data.toJson();
Support for custom objects but use fromJson & toJson instead of full object parsing:
UserModel:
path: webservice/user
properties:
description: The time at which the user has last updated his information
changedAt:
type: datetime
fromJson: handleFromJsonWithCustomCode
toJson: handleToJsonWithCustomCode
You can specify custom json converters to be used for types that match
UserModel:
path: webservice/user
converters:
- DateTimeConverter
properties:
changedAt:
type: datetime
Specify the custom JsonConverter object as a known type to resolve it
DateTimeConverter:
type: json_converter
path: converter/
You can specify description
on models, enum, fields and on enum entries. This description will be used verbatim to generate a code comment for that class/enum/field
UserModel:
path: webservice/user
description: The model holding user data
converters:
- DateTimeConverter
properties:
description: The time at which the user has last updated his information
changedAt:
type: datetime
You can specify static_create
on objects or globally in the pubspec.yaml
file. If this is specified, a static creator method called create
will be generated referencing the factory constructor. This static method can be used as a function reference. Defaults to false
UserModel:
path: webservice/user
static_create: true
properties:
changedAt:
type: datetime
Retrofit has added compute function support for decoding json payload in version 3.0.0. This requires top-level functions with a certain signature. You can have model generator generate these for you by setting retrofit_compute: true
in the pubspec.yaml file:
model_generator:
retrofit_compute: true
Run this command:
With Dart:
$ dart pub add model_generator
With Flutter:
$ flutter pub add model_generator
This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get
):
dependencies:
model_generator: ^5.8.1
Alternatively, your editor might support dart pub get
or flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:model_generator/config/pubspec_config.dart';
import 'package:model_generator/config/yml_generator_config.dart';
import 'package:model_generator/model/field.dart';
import 'package:model_generator/model/item_type/array_type.dart';
import 'package:model_generator/model/item_type/boolean_type.dart';
import 'package:model_generator/model/item_type/date_time_type.dart';
import 'package:model_generator/model/item_type/double_type.dart';
import 'package:model_generator/model/item_type/dynamic_type.dart';
import 'package:model_generator/model/item_type/integer_type.dart';
import 'package:model_generator/model/item_type/item_type.dart';
import 'package:model_generator/model/item_type/map_type.dart';
import 'package:model_generator/model/item_type/object_type.dart';
import 'package:model_generator/model/item_type/string_type.dart';
import 'package:model_generator/model/model/custom_from_to_json_model.dart';
import 'package:model_generator/model/model/custom_model.dart';
import 'package:model_generator/model/model/enum_model.dart';
import 'package:model_generator/model/model/json_converter_model.dart';
import 'package:model_generator/model/model/model.dart';
import 'package:model_generator/model/model/object_model.dart';
import 'package:model_generator/util/case_util.dart';
import 'package:model_generator/util/generic_type.dart';
import 'package:model_generator/util/keyword_helper.dart';
import 'package:model_generator/util/language_version.dart';
import 'package:model_generator/util/list_extensions.dart';
import 'package:model_generator/util/type_checker.dart';
import 'package:model_generator/writer/enum_model_writer.dart';
import 'package:model_generator/writer/object_model_writer.dart';
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:model_generator_example/app.dart';
Future<void> main() async {
runApp(MyApp());
}
Author: icapps
Source Code: https://github.com/icapps/flutter-model-generator
License: MIT license
1655908335
Swagger (OpenAPI) est une spécification indépendante du langage pour décrire les API REST. Il permet aux ordinateurs et aux humains de comprendre les capacités d'une API REST sans accès direct au code source. Swagger UI propose une interface utilisateur Web qui fournit des informations sur le service, à l'aide de la spécification OpenAPI générée. Swagger UI est une alternative à Postman.
Nous réalisons cet article dans le groupe de Swagger :relié :
Avec l'API Web REST, nous utilisons un verbe pour définir le comportement,
tandis que l'URI (nom) pour identifier une ressource. Cependant, parfois, les combinaisons de verbes et de noms ne suffisent pas à décrire les fonctionnalités de l'API Web. Par conséquent, plus d'explications pourraient être nécessaires pour le client REST. Cet article explique comment ajouter des commentaires C # dans Swagger.
Voici le contenu de l'article :
Forme spéciale des commentaires C#
Les commentaires ayant une certaine forme (spéciale) peuvent être utilisés pour ordonner à un outil de produire du XML à partir de ces commentaires et des éléments de code source qu'ils précèdent. Ces commentaires sont les Single-Line_Comment s ( §6.3.3 ) qui commencent par trois barres obliques ( ///
), ou Delimited_Comment s ( §6.3.3 ) qui commencent par une barre oblique et deux astérisques ( /**
).
Single_Line_Doc_Comment
: '///' Input_Character*
;
Delimited_Doc_Comment
: '/**' Delimited_Comment_Section* ASTERISK+ '/'
;
L'emplacement des commentaires spéciaux
Ils doivent précéder immédiatement un type défini par l'utilisateur ou un membre qu'ils annotent. Les sections d'attribut ( §21.3 ) sont considérées comme faisant partie des déclarations, donc les commentaires de documentation doivent précéder les attributs appliqués à un type ou un membre. Par exemple:
/// <summary>
/// This class performs an important function.
/// </summary>
public class MyClass{}
Écrivez des commentaires spéciaux dans un fichier XML par commande :
Lorsque vous compilez avec /doc , le compilateur recherche toutes les balises XML dans le code source et crée un fichier de documentation XML.
Vous pouvez voir un exemple de page de Comment : utiliser les fonctionnalités de documentation XML (Guide de programmation C#) | Microsoft Docs .
Dans du code,
Dans le fichier XML de sortie,
<member name="T:SomeClass">
<summary> Class level summary documentation goes here.</summary>
<remarks> Longer comments can be associated with a type or member through the remarks tag</remarks>
</member>
<member name="F:SomeClass.m_Name">
Écrivez des commentaires spéciaux dans l'API Web :
Code source:
Créez le fichier XML en tant que sortie : --- équivalent à l'utilisation de l' option /doc comipling en ligne de commande :
Cliquez avec le bouton droit sur le projet ==> Propriétés ==> Construire ==> sortie ==> Vérifier le fichier de document XML avec le chemin
Le fichier XML de sortie : --- À l'emplacement bin\WebBlogApi.xml
Cette forme originale fanfaronne, même si nous pouvons utiliser le verbe REST et le nom de l'API Web (nom) pour distinguer l'entité et l'anctionnalité, parfois il n'y en a toujours pas assez. Désormais, les commentaires spéciaux C # joueront un rôle.
Configurer Swagger
Une fois que nous avons le fichier XML avec les commentaires spéciaux C#, nous pouvons exporter les informations dans Swagger, en configurant Swagger :
Swagger avec commentaires spéciaux Remarques :
Créez le fichier XML en tant que sortie : --- équivalent à l'utilisation de l' option /doc comipling en ligne de commande :
Cliquez avec le bouton droit sur le projet ==> Propriétés ==> Construire ==> sortie ==> Vérifiez le fichier de document XML avec le chemin, c'est Visual Studio 2022 :
Le fichier XML de sortie : --- par défaut, accédez à l'emplacement bin\Debug\net5.0\WebBlogApi.xml
Ceci est pour .Net Core, sortie d'origine
Configurer Swagger
Swagger avec des notes de commentaires spéciaux
Référence
Source : https://www.c-sharpcorner.com/article/customized-swagger-for-net-mvc-web-api/
1655908200
Swagger (OpenAPI) es una especificación independiente del idioma para describir las API REST. Permite que tanto las computadoras como los humanos comprendan las capacidades de una API REST sin acceso directo al código fuente. La interfaz de usuario de Swagger ofrece una interfaz de usuario basada en web que proporciona información sobre el servicio mediante la especificación OpenAPI generada. Swagger UI es una alternativa a Postman.
Realizamos este artículo en el grupo de Swagger:relacionado:
Con REST Web API, usamos verbo para definir el comportamiento,
mientras que el URI (sustantivo) para identificar un recurso. Sin embargo, a veces, las combinaciones de verbos y sustantivos aún no son suficientes para describir las funciones de la API web. Por lo tanto, es posible que se necesiten más explicaciones para el cliente REST. Este artículo discutirá cómo agregar comentarios de C# en Swagger.
Este es el contenido del artículo:
Forma especial de comentarios de C#
Los comentarios que tienen una cierta forma (especial) se pueden usar para dirigir una herramienta para producir XML a partir de esos comentarios y los elementos del código fuente que preceden. Dichos comentarios son Single-Line_Comment s ( §6.3.3 ) que comienzan con tres barras inclinadas ( ///
), o Delimited_Comment s ( §6.3.3 ) que comienzan con una barra inclinada y dos asteriscos ( ). /**
Single_Line_Doc_Comment
: '///' Input_Character*
;
Delimited_Doc_Comment
: '/**' Delimited_Comment_Section* ASTERISK+ '/'
;
La ubicación de los comentarios especiales
Deben preceder inmediatamente a un tipo definido por el usuario o un miembro que anotan. Las secciones de atributos ( §21.3 ) se consideran parte de las declaraciones, por lo que los comentarios de la documentación deben preceder a los atributos aplicados a un tipo o miembro. Por ejemplo:
/// <summary>
/// This class performs an important function.
/// </summary>
public class MyClass{}
Escriba comentarios especiales en un archivo XML mediante el comando:
Cuando compila con /doc, el compilador buscará todas las etiquetas XML en el código fuente y creará un archivo de documentación XML.
Puede ver una página de muestra de Cómo: Usar las funciones de documentación XML (Guía de programación de C#) | Documentos de Microsoft .
En codigo,
En el archivo XML de salida,
<member name="T:SomeClass">
<summary> Class level summary documentation goes here.</summary>
<remarks> Longer comments can be associated with a type or member through the remarks tag</remarks>
</member>
<member name="F:SomeClass.m_Name">
Escriba comentarios especiales en la API web:
Código fuente:
Cree el archivo XML como una salida: --- equivalente a usar la opción /doc para compilar en la línea de comandos:
Haga clic con el botón derecho en el proyecto ==> Propiedades ==> Generar ==> salida ==> Verifique el archivo del documento XML con la ruta
El archivo XML de salida: --- En la ubicación en bin\WebBlogApi.xml
Esta forma original de fanfarronería, incluso podemos usar el verbo REST y el nombre de la API web (sustantivo) para distinguir la entidad y la funcionalidad, en algún momento todavía no hay suficientes. Ahora, los comentarios especiales de C# desempeñarán un papel.
Configurar Swagger
Una vez que tengamos el archivo XML con los comentarios especiales de C#, podemos exportar la información a Swagger configurando Swagger:
Swagger con comentarios especiales Notas:
Cree el archivo XML como una salida: --- equivalente a usar la opción /doc para compilar en la línea de comandos:
Haga clic derecho en el Proyecto ==> Propiedades ==> Generar ==> salida ==> Verifique el archivo del documento XML con la ruta, este es Visual Studio 2022:
El archivo XML de salida: --- por defecto ir a la ubicación en bin\Debug\net5.0\WebBlogApi.xml
Esto es para .Net Core, salida original
Configurar Swagger
Swagger con notas de comentarios especiales
Referencia
Fuente: https://www.c-sharpcorner.com/article/customized-swagger-for-net-mvc-web-api/