{"id":13872195,"url":"https://github.com/Apodini/Apodini","last_synced_at":"2025-07-16T01:33:10.377Z","repository":{"id":37448433,"uuid":"274515276","full_name":"Apodini/Apodini","owner":"Apodini","description":"Apodini - A declarative, composable server-side Swift framework","archived":false,"fork":false,"pushed_at":"2024-01-22T14:22:37.000Z","size":6427,"stargazers_count":87,"open_issues_count":55,"forks_count":11,"subscribers_count":10,"default_branch":"develop","last_synced_at":"2024-08-06T23:51:43.281Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://apodini.github.io/Apodini/","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Apodini.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSES/Apache-2.0.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-06-23T21:45:56.000Z","updated_at":"2024-06-30T19:38:28.000Z","dependencies_parsed_at":"2024-01-16T10:09:27.490Z","dependency_job_id":null,"html_url":"https://github.com/Apodini/Apodini","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":"Apodini/Template-Repository","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Apodini%2FApodini","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Apodini%2FApodini/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Apodini%2FApodini/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Apodini%2FApodini/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Apodini","download_url":"https://codeload.github.com/Apodini/Apodini/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226090030,"owners_count":17572114,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-05T23:00:36.320Z","updated_at":"2024-11-23T19:31:40.523Z","avatar_url":"https://github.com/Apodini.png","language":"Swift","funding_links":[],"categories":["Swift"],"sub_categories":[],"readme":"\u003c!--\n                  \nThis source file is part of the Apodini open source project\n\nSPDX-FileCopyrightText: 2019-2021 Paul Schmiedmayer and the Apodini project authors (see CONTRIBUTORS.md) \u003cpaul.schmiedmayer@tum.de\u003e\n\nSPDX-License-Identifier: MIT\n             \n--\u003e\n\n# Apodini\n[![DOI](https://zenodo.org/badge/274515276.svg)](https://zenodo.org/badge/latestdoi/274515276)\n[![codecov](https://codecov.io/gh/apodini/apodini/branch/develop/graph/badge.svg?token=QOAYN4SWRN)](https://codecov.io/gh/apodini/apodini)\n[![Build and Test](https://github.com/Apodini/Apodini/actions/workflows/push.yml/badge.svg)](https://github.com/Apodini/Apodini/actions/workflows/push.yml)\n\nApodini is a declarative, composable framework to build evolvable web services. It is part of a research project at the [TUM Research Group for Applied Software Engineering](https://ase.in.tum.de/schmiedmayer).\n\n## Getting Started\n\n### Installation\n\nApodini uses the Swift Package Manager:\n\nAdd it as a project-dependency:\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/Apodini/Apodini.git\", .branch(\"develop\"))\n]\n```\n\nAdd the base package and all exporters you want to use to your target:\n\n```swift\ntargets: [\n    .target(\n        name: \"Your Target\",\n        dependencies: [\n            .product(name: \"Apodini\", package: \"Apodini\"),\n            .product(name: \"ApodiniREST\", package: \"Apodini\"),\n            .product(name: \"ApodiniOpenAPI\", package: \"Apodini\")\n        ])\n]‚\n\n```\n\n### Hello World\n\nGetting started is really easy:\n\n```swift\nimport Apodini\nimport ApodiniREST\n\nstruct Greeter: Handler {\n    @Parameter var country: String?\n\n    func handle() -\u003e String {\n        \"Hello, \\(country ?? \"World\")!\"\n    }\n}\n\nstruct HelloWorld: WebService {\n    var configuration: Configuration {\n        REST()\n    }\n\n    var content: some Component {\n        Greeter()\n    }\n}\n\nHelloWorld.main()\n\n// http://localhost -\u003e Hello, World!\n// http://localhost?country=Italy -\u003e Hello, Italy!\n```\n\nApodini knows enough about your service to automatically generate OpenAPI docs. Just add the respective exporter:\n\n```swift\nimport ApodiniOpenAPI\n...\nstruct HelloWorld: WebService {\n    var configuration: Configuration {\n        REST { \n            OpenAPI()\n        }\n    }\n    ...\n}\n\n// JSON definition: http://localhost/openapi\n// Swagger UI: http://localhost/openapi-ui\n```\n\nWith `Binding`s we can re-use `Handler`s in different contexts:\n```swift\nstruct Greeter: Handler {\n    @Binding var country: String?\n\n    func handle() -\u003e String {\n        \"Hello, \\(country ?? \"World\")!\"\n    }\n}\n\nstruct HelloWorld: WebService {\n    var configuration: Configuration {\n        REST { \n            OpenAPI()\n        }\n    }\n\n    var content: some Component {\n        Greeter(country: nil)\n            .description(\"Say 'Hello' to the World.\")\n        Group(\"country\") {\n            CountrySubsystem()\n        }\n    }\n}\n\nstruct CountrySubsystem: Component {\n    @PathParameter var country: String\n    \n    var content: some Component {\n        Group($country) {\n            Greeter(country: Binding\u003cString?\u003e($country))\n                .description(\"Say 'Hello' to a country.\")\n        }\n    }\n}\n\n// http://localhost -\u003e Hello, World!\n// http://localhost/country/Italy -\u003e Hello, Italy!\n```\nApodini allows the developer to specify CLI-arguments that are passed to the `WebService`. The arguments can for example be used in `Configuration`:\n\n```swift\nstruct HelloWorld: WebService {\n    @Flag(help: \"Generate an OpenAPI documentation of the WebService.\")\n    var generateOpenAPIDocs = false\n    \n    var configuration: Configuration {\n        if(generateOpenAPIDocs) {\n            REST { \n                OpenAPI()\n            }\n        } else {\n            REST()\n        }\n    }\n}\n```\nFor further information on how to specify CLI-arguments see [https://github.com/apple/swift-argument-parser](https://github.com/apple/swift-argument-parser)\n\n## Documentation\n\nThe framework is a research project to enable the development of evolvable web services. You can find technical documentation of the functionality in the [Apodini DocC documentation](https://github.com/Apodini/Apodini/tree/develop/Sources/Apodini/Apodini.docc)\n\n## Contributing\nContributions to this project are welcome. Please make sure to read the [contribution guidelines](https://github.com/Apodini/.github/blob/main/CONTRIBUTING.md) first.\n\n## License\nThis project is licensed under the MIT License. See [License](https://github.com/Apodini/Apodini/blob/reuse/LICENSES/MIT.txt) for more information.\n\n## Code of conduct\nFor our code of conduct see [Code of conduct](https://github.com/Apodini/.github/blob/main/CODE_OF_CONDUCT.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FApodini%2FApodini","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FApodini%2FApodini","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FApodini%2FApodini/lists"}